﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
using Elements;
using EnumClassLibrary;
using Model;
using Image = System.Drawing.Image;

namespace WindowsTest
{
    public partial class ImageOprationForm : Form
    {
        private Bitmap curBitmap;
        private int iw, ih;
        public static List<string> allMedicine = new List<string>();

        public ImageOprationForm()
        {
            InitializeComponent();
        }

        #region Event

        #region 文件

        //Open file
        private void openFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //Load Image
            var open = new OpenFileDialog
            {
                Filter = "Image file(*.bmp;*.jpg;*.jpeg;*.gif;*.png;*.tif;*.tiff;*.wmf)|*.bmp;*.jpg;*.jpeg;*.gif;*.png;*.tif;*.tiff;*.wmf"
            };

            if (open.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    curBitmap = (Bitmap)Image.FromFile(open.FileName);
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message);
                }

                pictureBox1.Refresh();
                pictureBox1.Image = curBitmap;
                label1.Text = open.FileName.Substring(open.FileName.LastIndexOf('\\') + 1);
                iw = curBitmap.Width;
                ih = curBitmap.Height;
            }
        }

        //Save file
        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (pictureBox2.Image == null)
                return;

            var saveFileDialog = new SaveFileDialog
                                     {
                                         FileName = label2.Text,
                                         Filter = "TIF(文件)(*.TIF)|*.TIF|All File(*.*)|*.*"
                                     };

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                string str = saveFileDialog.FileName;
                pictureBox2.Image.Save(str, ImageFormat.Tiff);
            }
        }

        //Exit
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        //添加第一张图片
        private void button1_Click(object sender, EventArgs e)
        {
            //Load Image1
            var open = new OpenFileDialog
            {
                Filter = "Image file(*.bmp;*.jpg;*gif;*png;*tif;*wmf)|*.bmp;*.jpg;*gif;*png;*tif;*wmf"
            };

            if (open.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    pictureBox1.Refresh();
                    pictureBox1.Image = Image.FromFile(open.FileName);
                    label1.Text = "原图1";
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message);
                }
            }

            button1.Visible = false;
        }

        //添加第二张图片
        private void button2_Click(object sender, EventArgs e)
        {
            //Load Image2
            var open = new OpenFileDialog
            {
                Filter = "Image file(*.bmp;*.jpg;*gif;*png;*tif;*wmf)|*.bmp;*.jpg;*gif;*png;*tif;*wmf"
            };

            if (open.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    pictureBox2.Refresh();
                    pictureBox2.Image = Image.FromFile(open.FileName);
                    label2.Text = "原图2";
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message);
                }
            }

            button2.Visible = false;
        }

        #endregion

        #region 算法实现

        //聚集算法-主要通过不断地取离种子点最近均值的算法
        private void gatherArithmeticToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        #endregion

        #region 彩色图像处理

        //颜色变换
        private void colorChangeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
        }

        public static Bitmap ColorChange(Bitmap bm, ColorType color, byte x)
        {
            var w = bm.Width;
            var h = bm.Height;
            var data = bm.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();

                switch (color)
                {
                    case ColorType.Red:
                        for (int j = 0; j < h; j++)
                        {
                            for (int i = 0; i < w; i++)
                            {
                                var p = ptr + j * data.Stride + i * 3;
                                p[2] = x;
                            }
                        }
                        break;
                    case ColorType.Green:
                        for (int j = 0; j < h; j++)
                        {
                            for (int i = 0; i < w; i++)
                            {
                                var p = ptr + j * data.Stride + i * 3;
                                p[1] = x;
                            }
                        }
                        break;
                    case ColorType.Blue:
                        for (int j = 0; j < h; j++)
                        {
                            for (int i = 0; i < w; i++)
                            {
                                var p = ptr + j * data.Stride + i * 3;
                                p[0] = x;
                            }
                        }
                        break;
                    case ColorType.All:
                        for (int j = 0; j < h; j++)
                        {
                            for (int i = 0; i < w; i++)
                            {
                                var p = ptr + j * data.Stride + i * 3;
                                p[0] = p[1] = p[2] = x;
                            }
                        }
                        break;
                }
            }

            bm.UnlockBits(data);

            return bm;
        }

        #endregion

        #region 模式识别

        //模式识别
        private void DigitsRecogToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var dialog = new DigitsRecog();
            dialog.ShowDialog();
        }

        #endregion

        #region 图像压缩

        //应用颜色表
        private int mColor;
        private int imageWidth, imageHeight;
        private byte[] mData;
        private byte[] search, colors;
        private int numColors;

        //应用颜色表压缩
        private void colorCompressToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

        }

        private void colorUnZipToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void huffmanCompressToolStripMenuItem1_Click(object sender, EventArgs e)
        {

        }

        private void huffmanUnZipToolStripMenuItem1_Click(object sender, EventArgs e)
        {

        }

        private void rleCompressToolStripMenuItem2_Click(object sender, EventArgs e)
        {

        }

        private void rleUnZipToolStripMenuItem2_Click(object sender, EventArgs e)
        {

        }

        private void lzwCompressToolStripMenuItem3_Click(object sender, EventArgs e)
        {

        }

        private void lzwUnZipToolStripMenuItem3_Click(object sender, EventArgs e)
        {

        }

        private void dctCompressToolStripMenuItem4_Click(object sender, EventArgs e)
        {

        }

        private void dctUnZipToolStripMenuItem4_Click(object sender, EventArgs e)
        {

        }

        #endregion

        #region 二值形态学

        //腐蚀-正方结构
        private void erosion1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var gs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            gs = Matlab.Erode(gs, iw, ih, 1);
            var obm = Common.ToBitmap(gs);
            setResult(obm, "腐蚀结果");
        }

        //腐蚀-菱形结构
        private void erosion2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var gs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            gs = Matlab.Erode(gs, iw, ih, 2);
            var obm = Common.ToBitmap(gs);
            setResult(obm, "腐蚀结果");
        }

        //腐蚀-八角结构
        private void erosion3ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var gs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            gs = Matlab.Erode(gs, iw, ih, 3);
            var obm = Common.ToBitmap(gs);
            setResult(obm, "腐蚀结果");
        }

        //膨胀-正方结构
        private void dilation1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            bs = Matlab.Dilate(bm, bs, 1);
            var obm = Common.ToBitmap(bs);
            setResult(obm, "正方结构膨胀");
        }

        //膨胀-菱形结构
        private void dilation2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            bs = Matlab.Dilate(bm, bs, 2);
            var obm = Common.ToBitmap(bs);
            setResult(obm, "菱形结构膨胀");
        }

        //膨胀-八角结构
        private void dilation3ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            bs = Matlab.Dilate(bm, bs, 3);
            var obm = Common.ToBitmap(bs);
            setResult(obm, "八角结构膨胀");
        }

        //开启-正方结构
        private void open1ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            bs = Matlab.Erode(bs, iw, ih, 1);
            bs = Matlab.Dilate(bm, bs, 1);
            var obm = Common.ToBitmap(bs);
            setResult(obm, "正方结构开启");
        }

        //开启-菱形结构
        private void open2ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            bs = Matlab.Erode(bs, iw, ih, 2);
            bs = Matlab.Dilate(bm, bs, 2);
            var obm = Common.ToBitmap(bs);
            setResult(obm, "菱形结构开启");
        }

        //开启-八角结构
        private void open3ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            bs = Matlab.Erode(bs, iw, ih, 3);
            bs = Matlab.Dilate(bm, bs, 3);
            var obm = Common.ToBitmap(bs);
            setResult(obm, "八角结构开启");
        }

        //闭合-正方结构
        private void close1ToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            bs = Matlab.Dilate(bm, bs, 1);
            bs = Matlab.Erode(bs, iw, ih, 1);
            var obm = Common.ToBitmap(bs);
            setResult(obm, "正方结构闭合");
        }

        //闭合-菱形结构
        private void close2ToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            bs = Matlab.Dilate(bm, bs, 2);
            bs = Matlab.Erode(bs, iw, ih, 2);
            var obm = Common.ToBitmap(bs);
            setResult(obm, "菱形结构闭合");
        }

        //闭合-八角结构
        private void close3ToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            bs = Matlab.Dilate(bm, bs, 3);
            bs = Matlab.Erode(bs, iw, ih, 3);
            var obm = Common.ToBitmap(bs);
            setResult(obm, "八角结构闭合");
        }

        //噪声滤波-正方结构
        private void textStructureToolStripMenuItem4_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            //正方结构开启
            bs = Matlab.Erode(bs, iw, ih, 1);
            bs = Matlab.Dilate(bm, bs, 1);

            //正方结构闭合
            bs = Matlab.Dilate(bm, bs, 1);
            bs = Matlab.Erode(bs, iw, ih, 1);
            var obm = Common.ToBitmap(bs);
            setResult(obm, "正方结构滤波");

            //GetCurrentImage();
            //var bm = new Bitmap(curBitmap);
            //var gs = Matlab.toGray(bm, iw, ih);

            ////开启
            //gs = Matlab.grayErode(gs, iw, ih, 1);
            //gs = Matlab.grayDilate(gs, iw, ih, 1);

            ////闭合
            //gs = Matlab.grayDilate(gs, iw, ih, 1);
            //gs = Matlab.grayErode(gs, iw, ih, 1);

            //Bitmap obm = Common.toBitmap(gs);
            //SetResult(obm, "滤波结果");
        }

        //噪声滤波-菱形结构
        private void diamondStructureToolStripMenuItem4_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            //正方结构开启
            bs = Matlab.Erode(bs, iw, ih, 2);
            bs = Matlab.Dilate(bm, bs, 2);

            //正方结构闭合
            bs = Matlab.Dilate(bm, bs, 2);
            bs = Matlab.Erode(bs, iw, ih, 2);
            var obm = Common.ToBitmap(bs);
            setResult(obm, "菱形结构滤波");

            //GetCurrentImage();
            //var bm = new Bitmap(curBitmap);
            //var gs = Matlab.toGray(bm, iw, ih);

            ////闭合
            //gs = Matlab.grayDilate(gs, iw, ih, 1);
            //gs = Matlab.grayErode(gs, iw, ih, 1);

            ////开启
            //gs = Matlab.grayErode(gs, iw, ih, 1);
            //gs = Matlab.grayDilate(gs, iw, ih, 1);

            //var obm = Common.toBitmap(gs);
            //SetResult(obm, "滤波结果");
        }

        //噪声滤波-八角结构
        private void octagonalStructureToolStripMenuItem4_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            //正方结构开启
            bs = Matlab.Erode(bs, iw, ih, 3);
            bs = Matlab.Dilate(bm, bs, 3);

            //正方结构闭合
            bs = Matlab.Dilate(bm, bs, 3);
            bs = Matlab.Erode(bs, iw, ih, 3);
            var obm = Common.ToBitmap(bs);
            setResult(obm, "八角结构滤波");

            //GetCurrentImage();
            //var bm = new Bitmap(curBitmap);
            //var gs = Matlab.toGray(bm, iw, ih);

            ////开启
            //gs = Matlab.grayErode(gs, iw, ih, 1);
            //gs = Matlab.grayDilate(gs, iw, ih, 1);
            ////闭合
            //gs = Matlab.grayDilate(gs, iw, ih, 1);
            //gs = Matlab.grayErode(gs, iw, ih, 1);
            ////闭合
            //gs = Matlab.grayDilate(gs, iw, ih, 1);
            //gs = Matlab.grayErode(gs, iw, ih, 1);
            ////开启
            //gs = Matlab.grayErode(gs, iw, ih, 1);
            //gs = Matlab.grayDilate(gs, iw, ih, 1);

            //var obm = Common.toBitmap(gs);
            //SetResult(obm, "滤波结果");
        }

        //边界提取-正方结构
        private void getEdge1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            var bm = new Bitmap(curBitmap);
            byte[,] bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            //边界提取
            bs = Matlab.Edge(bs, 1);

            Bitmap obm = Common.ToBitmap(bs);
            setResult(obm, "正方结构边界提取");
        }

        //边界提取-菱形结构
        private void getEdge2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            //边界提取
            bs = Matlab.Edge(bs, 2);
            var obm = Common.ToBitmap(bs);

            setResult(obm, "菱形结构边界提取");
        }

        //边界提取-八角结构
        private void getEdge3ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            byte[,] bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            //边界提取
            bs = Matlab.Edge(bs, 3);
            var obm = Common.ToBitmap(bs);

            setResult(obm, "八角结构边界提取");
        }

        #endregion

        #region 图像效果

        //灰度形态学-腐蚀
        private void grayErosionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var gs = Matlab.ToGray(ref bm);
            gs = Matlab.GrayErode(gs, iw, ih, 1);
            var obm = Common.ToBitmap(gs);
            setResult(obm, "腐蚀结果");
        }

        //灰度形态学-膨胀
        private void grayDilationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var gs = Matlab.ToGray(ref bm);
            gs = Matlab.GrayDilate(gs, iw, ih, 1);
            var obm = Common.ToBitmap(gs);
            setResult(obm, "膨胀结果");
        }

        //灰度形态学-开启
        private void grayOpenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var gs = Matlab.ToGray(ref bm);
            gs = Matlab.GrayErode(gs, iw, ih, 1);
            gs = Matlab.GrayDilate(gs, iw, ih, 1);

            var obm = Common.ToBitmap(gs);
            setResult(obm, "开启结果");
        }

        //灰度形态学-闭合
        private void grayCloseToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var gs = Matlab.ToGray(ref bm);
            gs = Matlab.GrayDilate(gs, iw, ih, 1);
            gs = Matlab.GrayErode(gs, iw, ih, 1);

            var obm = Common.ToBitmap(gs);
            setResult(obm, "闭合结果");
        }

        //HMT变换
        private void hMTToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            //HMT变换
            var obm = Matlab.Hmt(bm, bs, iw, ih);
            setResult(obm, "HMT变换");
        }

        //浮雕效果
        private void EmbossToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            bm = ImageEffects.EmbossEffect(bm);
            setResult(bm, "浮雕效果");
        }

        //雾化效果
        private void fogEffectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            bm = ImageEffects.FogEffect(bm);
            setResult(bm, "雾化效果");
        }

        //柔化效果
        private void softEffectsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            bm = ImageEffects.SoftEffect(bm);
            setResult(bm, "柔化效果");
        }

        //镶嵌效果
        private void inlayEffectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            bm = ImageEffects.InlayEffect(bm);
            setResult(bm, "镶嵌效果");
        }

        //平滑效果
        private void SmoothEffectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            bm = ImageEffects.SmoothEffect(bm);
            setResult(bm, "平滑效果");
        }

        //霓虹效果
        private void neonEffectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            bm = ImageEffects.NeonEffect(bm);
            setResult(bm, "霓虹效果");
        }

        #endregion

        #region 图像增强

        //空域增强-对比度扩展
        private void contrastStretchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new strechDialog();
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                var x1 = Convert.ToInt32(dialog.getX1);
                var y1 = Convert.ToInt32(dialog.getY1);
                var x2 = Convert.ToInt32(dialog.getX2);
                var y2 = Convert.ToInt32(dialog.getY2);

                //计算灰度映射表
                var pixMap = ImageEnhancing.PixelsMap(x1, y1, x2, y2);

                //线性拉伸
                bm = ImageEnhancing.Stretch(bm, pixMap);

                setResult(bm, "对比度扩展");
            }
        }

        //空域增强-直方图均衡化
        private void histQualToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            //获得直方图
            var hist = Matlab.GetHist(bm);

            //直方图均衡化
            bm = ImageEnhancing.HistQual(bm, hist);

            setResult(bm, "直方图均衡化结果");
        }

        //空域增强-显示直方图
        private void histMapToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image != null && pictureBox2.Image != null)
            {
                var bm1 = new Bitmap(pictureBox1.Image);
                var bm2 = new Bitmap(pictureBox2.Image);

                var hist1 = Matlab.GetHist(bm1);
                var hist2 = Matlab.GetHist(bm2);

                Matlab.DrawHist(hist1, pictureBox1);
                Matlab.DrawHist(hist2, pictureBox2);

                label1.Text = "原图直方图";
                label2.Text = "均衡化后直方图";
            }
        }

        //空域增强-阈值滤波
        private void thresholdZonalFilteringToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            bm = ImageEnhancing.Threshold(bm);
            setResult(bm, "阈值滤波结果");
        }

        //空域增强-均值滤波
        private void averageFilteringToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            bm = ImageEnhancing.Average(bm);
            setResult(bm, "平均值滤波结果");
        }

        //空域增强-中值滤波
        private void mediumZonalFilteringToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new medianDialog();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                int num = dialog.getRadioNum();
                //中值滤波
                bm = ImageEnhancing.Median(bm, num);
                var str = "";
                switch (num)
                {
                    case 1:
                        str = "1X5窗口滤波结果";
                        break;
                    case 2:
                        str = "5X1窗口滤波结果";
                        break;
                    case 3:
                        str = "5X5窗口滤波结果";
                        break;
                }
                setResult(bm, str);
            }
        }

        //空域增强-低通滤波
        private void lowPassFilteringToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new medianDialog
                {
                    Text = "低通模板选择",
                    radioButton1 = { Text = "h1" },
                    radioButton2 = { Text = "h2" },
                    radioButton3 = { Text = "h3" }
                };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                var num = dialog.getRadioNum();

                //低通滤波
                bm = ImageEnhancing.LowPass(bm, num);
                var str = "";
                if (num == 1) str = "h1模板低通滤波结果";
                else if (num == 2) str = "h2模板低通滤波结果";
                else if (num == 3) str = "h3模板低通滤波结果";

                setResult(bm, str);
            }
        }

        //空域增强-高通滤波
        private void highPassFilteringToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new highPassDialog();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                var num = dialog.getRadioNum();

                //高通滤波
                bm = ImageEnhancing.HighPass(bm, num);
                var str = "";
                switch (num)
                {
                    case 1:
                        str = "H1模板高通滤波结果";
                        break;
                    case 2:
                        str = "H2模板高通滤波结果";
                        break;
                    case 3:
                        str = "H3模板高通滤波结果";
                        break;
                    case 4:
                        str = "H4模板高通滤波结果";
                        break;
                    case 5:
                        str = "H5模板高通滤波结果";
                        break;
                }
                setResult(bm, str);
            }
        }

        //图片锐化-kirsch算子
        private void kirsch1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.Detect(bm, 1);
            setResult(obm, "Kirsch算子锐化结果");
        }

        //图片锐化-laplace算子
        private void laplace1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.Detect(bm, 2);
            setResult(obm, "Laplace算子锐化结果");
        }

        //图片锐化-prewitt算子
        private void prewitt1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.Detect(bm, 3);
            setResult(obm, "Prewitt算子锐化结果");
        }

        //图片锐化-roberts算子
        private void roberts1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.Detect(bm, 4);
            setResult(obm, "Roberts算子锐化结果");
        }

        //图片锐化-sobel算子
        private void sobel1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.Detect(bm, 5);
            setResult(obm, "Sobel算子锐化结果");
        }

        //边界加强图片锐化-kirsch算子
        private void kirschToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.DetectWithColor(bm, 1);
            setResult(obm, "Kirsch算子锐化结果");
        }

        //边界加强图片锐化-laplace算子
        private void laplaceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.DetectWithColor(bm, 2);
            setResult(obm, "Laplace算子锐化结果");
        }

        //边界加强图片锐化-prewitt算子
        private void prewittToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.DetectWithColor(bm, 3);
            setResult(obm, "Prewitt算子锐化结果");
        }

        //边界加强图片锐化-roberts算子
        private void robertsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.DetectWithColor(bm, 4);
            setResult(obm, "Roberts算子锐化结果");
        }

        //边界加强图片锐化-sobel算子
        private void sobelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.DetectWithColor(bm, 5);
            setResult(obm, "Sobel算子锐化结果");
        }

        //灰度图像锐化-kirsch算子
        private void kirsch2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.DetectWithGray(bm, 1);
            setResult(obm, "Kirsch算子锐化结果");
        }

        //灰度图像锐化-laplace算子
        private void laplace2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.DetectWithGray(bm, 2);
            setResult(obm, "Laplace算子锐化结果");
        }

        //灰度图像锐化-prewitt算子
        private void prewitt2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.DetectWithGray(bm, 3);
            setResult(obm, "Prewitt算子锐化结果");
        }

        //灰度图像锐化-roberts算子
        private void roberts2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.DetectWithGray(bm, 4);
            setResult(obm, "Roberts算子锐化结果");
        }

        //灰度图像锐化-sobel算子
        private void sobel2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = Matlab.DetectWithGray(bm, 5);
            setResult(obm, "Sobel算子锐化结果");
        }

        //拉普拉斯锐化
        private void laplaceDetectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var newBitmap = new Bitmap(iw, ih);
            var data = bm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            var dataNew = newBitmap.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.WriteOnly,
                                             PixelFormat.Format24bppRgb);

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();
                var ptrN = (byte*)dataNew.Scan0.ToPointer();

                //拉普拉斯模板
                int[] laplacian = { -1, -1, -1, -1, 9, -1, -1, -1, -1 };
                for (int i = 1; i < iw - 1; i++)
                {
                    for (int j = 1; j < ih - 1; j++)
                    {
                        int r = 0, g = 0, b = 0;
                        int index = 0;
                        for (int k = -1; k <= 1; k++)
                        {
                            for (int l = -1; l <= 1; l++)
                            {
                                var p = ptr + (j + k) * iw * 3 + (data.Stride - iw * 3) * (j + k) + (i + l) * 3;
                                r += p[2] * laplacian[index];
                                g += p[1] * laplacian[index];
                                b += p[0] * laplacian[index];
                                index++;
                            }
                        }

                        //处理颜色值溢出
                        r = r > 255 ? 255 : r;
                        r = r < 0 ? 0 : r;
                        g = g > 255 ? 255 : g;
                        g = g < 0 ? 0 : g;
                        b = b > 255 ? 255 : b;
                        b = b < 0 ? 0 : b;

                        var pt = ptrN + (j - 1) * iw * 3 + (dataNew.Stride - iw * 3) * (j - 1) + (i - 1) * 3;
                        pt[0] = (byte)b;
                        pt[1] = (byte)g;
                        pt[2] = (byte)r;
                    }
                }
            }

            bm.UnlockBits(data);
            newBitmap.UnlockBits(dataNew);
            setResult(newBitmap, "锐化结果");
        }

        #endregion

        #region 图像分析

        //轮廓跟踪
        private int inum;//轮廓点数
        private int[] nCurrX;//轮廓坐标X
        private int[] nCurrY;//轮廓坐标Y
        private int[] codes;//链码
        private int[] ncodes;//规范链码
        private void contourTracingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = new Bitmap(curBitmap);

            byte[,] bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var st = Matlab.FindStart(bs, iw, ih);
            var nst = Matlab.OutLine(bs, st[0], st[1], iw, ih);

            //用红色小方块标注链码起始点
            for (int i = -2; i < 3; i++)
            {
                for (int j = -2; j < 3; j++)
                {
                    bm.SetPixel(st[0] + i, st[1] + j, Color.FromArgb(255, 0, 0));
                }
            }

            //重置初始化二值图像
            for (int j = 0; j < ih; j++)
            {
                for (int i = 0; i < iw; i++)
                {
                    obm.SetPixel(i, j, Color.FromArgb(255, 255, 255));
                }
            }

            //写入边界点
            for (int i = 0; i < inum; i++)
            {
                obm.SetPixel(nCurrX[i], nCurrY[i], Color.FromArgb(0, 0, 0));
            }

            //用红色小方块标注规范链码起始点
            for (int i = -2; i < 3; i++)
            {
                for (int j = -2; j < 3; j++)
                {
                    obm.SetPixel(nst[0] + i, nst[1] + j, Color.FromArgb(255, 0, 0));
                }
            }

            pictureBox1.Refresh();
            var g = pictureBox1.CreateGraphics();
            g.DrawImage(bm, 0, 0);
            g.DrawString("红色方块为超点：(" + st[0] + "," + st[1] + ")", Font, new SolidBrush(Color.Blue), 0, 240);
            pictureBox2.Refresh();
            g = pictureBox2.CreateGraphics();
            g.DrawImage(obm, 0, 0);
            g.DrawString("红色方块为起点：(" + nst[0] + "," + nst[1] + ")", Font, new SolidBrush(Color.Blue), 0, 240);
            label2.Text = "轮廓跟踪图";
        }

        //边界检测
        private void edgeToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var p = new HiPerfTimer();
            p.Start();
            var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            bm = Matlab.BoundDetect(bm, bs, iw, ih);
            p.Stop();
            setResult(bm, "边界检测结果 用时：" + p.Duration);
        }

        //边界提取
        private void edgeDetectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            byte[,] bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            //边界提取
            bs = Matlab.Edge(bs, 15);
            var obm = Common.ToBitmap(bs);

            setResult(obm, "边界提取");
        }

        //消除小洞
        private void deleteHoleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new holeAreaDialog();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                var holeArea = Convert.ToInt32(dialog.getHoleArea);
                var bs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
                var p = new HiPerfTimer();
                p.Start();
                var obm = Matlab.DelHole(bm, bs, holeArea);
                p.Stop();
                setResult(obm, "消除小洞结果 用时：" + p.Duration);
            }
        }

        //检测直线-检测横线
        private void HorizontalBlackAreaLineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            var bm = new Bitmap(curBitmap);
            var gs = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            var line = Matlab.HorizontalLine(gs, iw, ih, 0.6f);

            for (int j = 0; j < ih; j++)
            {
                foreach (var l in line)
                {
                    if (l.A == j)
                    {
                        for (int i = 0; i < iw; i++)
                        {
                            bm.SetPixel(i, j, Color.FromArgb(255, 0, 0));
                        }
                    }
                }
            }

            setResult(bm, "检测到的横线");
        }

        //检测直线-检测竖线
        private void VerticalBlackAreaLineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            var bm = new Bitmap(curBitmap);
            var gs = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var line = Matlab.VerticalLine(gs, iw, ih, 0.2f);

            for (int i = 0; i < iw; i++)
            {
                foreach (var l in line)
                {
                    if (l.A == i)
                    {
                        for (int j = 0; j < ih; j++)
                        {
                            bm.SetPixel(i, j, Color.FromArgb(255, 0, 0));
                        }
                    }
                }
            }

            setResult(bm, "检测到的竖线");
        }

        //检测直线
        private void detectLineToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            var bm = new Bitmap(curBitmap);
            var im = new byte[ih, iw];
            var data = bm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

            unsafe
            {
                var ptr = (byte*)data.Scan0;
                for (int i = 0; i < ih; i++)
                {
                    for (int j = 0; j < iw; j++)
                    {
                        im[i, j] = ((ptr[0] + ptr[1] + ptr[2]) / 3) > 128 ? (byte)0 : (byte)1;
                        ptr += 3;
                    }
                    ptr += data.Stride - iw * 3;
                }
            }

            bm.UnlockBits(data);

            var gs = Matlab.DetecLine(im, iw, ih);
            var obm = Common.ToBitmap(gs);

            setResult(obm, "检测到的直线");
        }

        //直方图
        private void histToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var hist = Matlab.GetHist(bm);
            Matlab.DrawHist(hist, pictureBox2);
            label2.Text = "直方图";
        }

        //灰度中值
        private void grayMedianToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            pictureBox2.Refresh();
            var g = pictureBox2.CreateGraphics();
            g.Clear(Color.FromArgb(224, 224, 224));
            g.DrawString("左上角坐标为（100X100）的5X5块的灰度值为\n", pictureBox2.Font, new SolidBrush(Color.Blue), 20, 10);

            var pix = new int[25];
            for (int j = 0; j < 5; j++)
            {
                for (int i = 0; i < 5; i++)
                {
                    pix[i + j * 5] = bm.GetPixel(100 + i, 100 + i).B;
                    g.DrawString(" " + pix[i + j * 5], pictureBox2.Font, new SolidBrush(Color.Blue), 20 + i * 50, 30 + j * 15);
                }
            }

            //排序
            pix = Matlab.MedianSorter(pix, 25);

            g.DrawString("排序如下：", Font, new SolidBrush(Color.Blue), 20, 130);

            for (int i = 0; i < 8; i++)
            {
                g.DrawString(" " + pix[i], Font, new SolidBrush(Color.Blue), 20 + i * 50, 150);
            }

            for (int i = 0; i < 8; i++)
            {
                g.DrawString(" " + pix[8 + i], Font, new SolidBrush(Color.Blue), 20 + i * 50, 170);
            }

            for (int i = 0; i < 9; i++)
            {
                g.DrawString(" " + pix[16 + i], Font, new SolidBrush(Color.Blue), 20 + i * 50, 190);
            }

            g.DrawString("中值=" + pix[12], Font, new SolidBrush(Color.Blue), 20, 220);
            label2.Text = "灰度中值";
        }

        //灰度平均值
        private void grayAverToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            double sum = 0.0;

            //计算平均值
            var data = bm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();
                for (int j = 0; j < ih; j++)
                {
                    for (int i = 0; i < iw; i++)
                    {
                        sum += (ptr + j * data.Stride + i * 3)[2];
                    }
                }
            }

            bm.UnlockBits(data);

            double aver = sum / (iw * ih);

            pictureBox2.Refresh();
            var g = pictureBox2.CreateGraphics();
            g.Clear(Color.FromArgb(224, 224, 224));
            g.DrawString("灰度平均值 \n A = " + aver, Font, new SolidBrush(Color.Blue), 10, 100);
            label2.Text = "灰度平均值";
        }

        //计算形心 
        private void centerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            Matlab.ToGray(ref bm);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var obm = Common.ToBitmap(im);
            var centerxy = new int[2];
            obm = Matlab.Center(obm, im, ref centerxy);
            setResult(obm, "形心坐标（" + centerxy[0] + "," + centerxy[1] + ")");
        }

        //计算角度
        private void degreeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var dialog = new degreeDialog();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var a = Convert.ToInt32(dialog.geta());
                var b = Convert.ToInt32(dialog.getb());

                var tanA = (double)a / b;
                MessageBox.Show("A=" + ImageCorrect.GetDegree(tanA) + "度", "Message box");
            }
        }

        //获取行高
        private void getLineHeightToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            MessageBox.Show(CharactersSegmentation.GetLineHeight(bm).ToString(), "Message");
        }

        //获取单分量图
        private void getSingleComponentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
        }

        //字块分析
        private void blockAnalysisToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            byte[,] gs;
            byte[,] im = gs = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            var recList = ConnexBlock.GetConnexBlock(im, ref gs);

            var data = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadWrite,
                                   PixelFormat.Format24bppRgb);
            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();

                foreach (var rectangle in recList)
                {
                    for (int i = rectangle.X; i <= rectangle.X + rectangle.Width; i++)
                    {
                        var ju = rectangle.Y;
                        var jd = rectangle.Y + rectangle.Height;

                        var _pu = ptr + ju * data.Stride + i * 3;
                        var _pd = ptr + jd * data.Stride + i * 3;
                        _pu[2] = _pd[2] = 255;
                        _pu[1] = _pd[1] = 0;
                        _pu[0] = _pd[0] = 0;
                    }

                    for (int j = rectangle.Y; j <= rectangle.Y + rectangle.Height; j++)
                    {
                        var il = rectangle.X;
                        var ir = rectangle.X + rectangle.Width;

                        var _pl = ptr + j * data.Stride + il * 3;
                        var _pr = ptr + j * data.Stride + ir * 3;
                        _pl[2] = _pr[2] = 255;
                        _pl[1] = _pr[1] = 0;
                        _pl[0] = _pr[0] = 0;
                    }
                }
            }
            bm.UnlockBits(data);
            setResult(bm, "找连通区域结果");
        }

        #endregion

        #region 图形细化

        //图形细化-算法一
        private void thinnerOneToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            im = Matlab.Thinner1(im);
            var obm = Common.ToBitmap(im);
            setResult(obm, "图形细化算法一");
        }

        //图形细化-算法二
        private void thinnerTwoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            im = Matlab.Thinner2(im);
            var obm = Common.ToBitmap(im);
            setResult(obm, "图形细化算法二");
        }

        #endregion

        #region 图像处理

        //彩色转灰度图像
        private void toGrayToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);

            var pt = new HiPerfTimer();
            pt.Start();

            Matlab.ToGray(ref bm);

            pt.Stop();
            setResult(bm, "灰度图像 用时：" + pt.Duration);
        }

        //灰度线性变换
        private void grayLinearTransformationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new linTransDialog();
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var p = Convert.ToDouble(dialog.getP);
                var q = Convert.ToInt32(dialog.getQ);

                //灰度线性变换
                var bm = new Bitmap(curBitmap);
                var pt = new HiPerfTimer();
                pt.Start();
                bm = Matlab.Linetrans(bm, iw, ih, p, q);
                pt.Stop();
                setResult(bm, "线性变换结果 用时：" + pt.Duration);
            }
        }

        //伪彩色处理
        private void pseudoColorProcessingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //伪彩色处理
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var pt = new HiPerfTimer();
            pt.Start();
            bm = Matlab.FalseColorTrans(bm, iw, ih, 64, 192);
            pt.Stop();
            setResult(bm, "伪彩色处理结果 用时：" + pt.Duration);
        }

        //图片融合
        private void imageFusionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image != null && pictureBox2.Image != null)
            {
                var b1 = new Bitmap(pictureBox1.Image);
                var b2 = new Bitmap(pictureBox2.Image);

                int w = b1.Width < b2.Width ? b1.Width : b2.Width;
                int h = b1.Height < b2.Height ? b1.Height : b2.Height;

                var pt = new HiPerfTimer();
                pt.Start();
                //图像融合
                b2 = Matlab.Combine(b1, b2, w, h);
                pt.Stop();

                pictureBox2.Refresh();
                pictureBox2.Image = b2;
                label2.Text = "图像融合结果 用时：" + pt.Duration;
            }
            else
            {
                button1.Visible = true;
                button2.Visible = true;
            }
        }

        //灰度阈值变换
        private void thresholdTranslationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new inputDialog();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var th = Convert.ToInt32(dialog.getThresh);

                //阈值变换
                var bm = new Bitmap(curBitmap);

                var pt = new HiPerfTimer();
                pt.Start();
                bm = Matlab.Thresh(bm, iw, ih, th);
                pt.Stop();

                setResult(bm, "灰度阈值变换结果 用时：" + pt.Duration);
            }
        }

        //最佳灰度阈值变换
        private void bestThresholdTranslationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var pt = new HiPerfTimer();
            pt.Start();
            var t = Matlab.GetThreshold(bm);
            bm = Matlab.Thresh(bm, iw, ih, t);
            pt.Stop();

            setResult(bm, "最佳灰度阈值变换 最佳阈值：" + t + " 用时：" + pt.Duration);
        }

        //平均灰度阈值变换
        private void averThresholdToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new threshDialog();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var nx = dialog.getNx();
                var ny = dialog.getNy();

                var bm = new Bitmap(curBitmap);
                var pt = new HiPerfTimer();
                pt.Start();
                bm = Matlab.AverThresh(bm, nx, ny);
                pt.Stop();

                setResult(bm, "平均灰度阈值变换 用时：" + pt.Duration);
            }
        }

        //八邻域阈值分割
        private void eightNorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var im = Matlab.ToGray(ref bm);
            var data = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadWrite,
                                   PixelFormat.Format24bppRgb);

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();
                for (int j = 1; j < bm.Height - 1; j++)
                {
                    for (int i = 1; i < bm.Width - 1; i++)
                    {
                        var s = 0;
                        for (int k = -1; k < 2; k++)
                        {
                            for (int l = -1; l < 2; l++)
                            {
                                var p = ptr + (j + k) * data.Stride + (i + l) * 3;
                                s += p[2];
                            }
                        }
                        var ave = s / 9;

                        im[i, j] = (ave > 160) ? 255 : 0;
                    }
                }

                for (int j = 0; j < bm.Height; j++)
                {
                    for (int i = 0; i < bm.Width; i++)
                    {
                        var p = ptr + j * data.Stride + i * 3;
                        if (i == 0 || j == 0)
                        {
                            p[0] = p[1] = p[2] = 255;
                        }
                        else
                        {
                            p[0] = p[1] = p[2] = (byte)im[i, j];
                        }
                    }
                }
            }

            bm.UnlockBits(data);
            setResult(bm, "八邻域阈值分割");
        }

        //C++二值化
        private void cTwoValueToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var imageData = Common.BitmapToBytes(bm);
            Matlab.ThreeValue(imageData, bm.Width, bm.Height, 3 * 3 * 390);
            var im = new byte[bm.Width, bm.Height];
            for (int j = 0; j < bm.Height; j++)
            {
                for (int i = 0; i < bm.Width; i++)
                {
                    if (imageData[j * bm.Width + i] < 100)
                    {
                        im[i, j] = 1;
                    }
                    else
                    {
                        im[i, j] = 0;
                    }
                }
            }
            bm = Common.ToBitmap(im);

            setResult(bm, "二值化结果");
        }

        //单分量阈值分割-R分量
        private void rComponentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var t = Matlab.GetThresholdByOneComponent(bm, "R");
            bm = Matlab.Thresh(bm, iw, ih, t);
            setResult(bm, "R分量分割");
        }

        //单分量阈值分割-G分量
        private void gComponentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var t = Matlab.GetThresholdByOneComponent(bm, "G");
            bm = Matlab.Thresh(bm, iw, ih, t);
            setResult(bm, "G分量分割");
        }

        //单分量阈值分割-B分量
        private void bComponentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var t = Matlab.GetThresholdByOneComponent(bm, "B");
            bm = Matlab.Thresh(bm, iw, ih, t);
            setResult(bm, "B分量分割");
        }

        //描黑（刮花）
        private void blackRowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);

            var pt = new HiPerfTimer();
            pt.Start();
            //二值化影像
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            //将采样的影像二值化
            im = Matlab.Horizontal2ValueSampling(im, 32);
            var obm = Common.ToBitmap(im);
            pt.Stop();
            setResult(obm, "刮花结果 用时：" + pt.Duration);
        }

        //去线条
        private void deleteLineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 6, 192, iw);//找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 6, 64, ih);//找竖线
            var data = bm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();

                //去横线
                foreach (var line in hLines)
                {
                    for (int i = line.B_Min; i <= line.B_Max; i++)
                    {
                        var _ptr = ptr + line.A * data.Stride + i * 3;
                        _ptr[2] = 255;
                        _ptr[1] = 255;
                        _ptr[0] = 255;
                    }
                }

                //去竖线
                foreach (var line in vLines)
                {
                    for (int j = line.B_Min; j <= line.B_Max; j++)
                    {
                        var _ptr = ptr + j * data.Stride + line.A * 3;
                        _ptr[2] = 255;
                        _ptr[1] = 255;
                        _ptr[0] = 255;
                    }
                }
            }

            bm.UnlockBits(data);
            setResult(bm, "去线条结果");
        }

        //采样-普通采样
        private void normalSamplingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog { groupBox1 = { Text = "输入采样间隔(1/2/4/8/16)" }, label1 = { Text = "采样间隔" } };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                int d = Convert.ToInt32(dialog.getParam);//采样间隔
                var bm = new Bitmap(curBitmap);
                BitmapData data = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadWrite,
                                              PixelFormat.Format24bppRgb);
                int stride = data.Stride;

                var p = new HiPerfTimer();
                p.Start();

                unsafe
                {
                    var ptr = (byte*)data.Scan0.ToPointer();
                    int dd = d * d;
                    for (int j = 0; j < ih; j = j + d)
                    {
                        for (int i = 0; i < iw; i = i + d)
                        {
                            int r = 0, g = 0, b = 0;
                            for (int k = 0; k < d; k++)
                            {
                                for (int l = 0; l < d; l++)
                                {
                                    var x = i + k >= iw ? iw - 1 : i + k;
                                    var y = j + l >= ih ? ih - 1 : j + l;
                                    r = r + (ptr + y * stride + (x * 3))[2];
                                    g = g + (ptr + y * stride + (x * 3))[1];
                                    b = b + (ptr + y * stride + (x * 3))[0];
                                }
                            }

                            r = r / dd;
                            g = g / dd;
                            b = b / dd;

                            for (int k = 0; k < d; k++)
                            {
                                for (int l = 0; l < d; l++)
                                {
                                    var x = i + k >= iw ? iw - 1 : i + k;
                                    var y = j + l >= ih ? ih - 1 : j + l;
                                    (ptr + y * stride + (x * 3))[2] = (byte)r;
                                    (ptr + y * stride + (x * 3))[1] = (byte)g;
                                    (ptr + y * stride + (x * 3))[0] = (byte)b;
                                }

                            }
                        }
                    }
                }

                bm.UnlockBits(data);
                p.Stop();
                setResult(bm, "普通采样 用时：" + p.Duration);
            }
        }

        //采样-横向采样
        private void horizontalSamplingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog { groupBox1 = { Text = "输入采样间隔(1/2/4/8/16)" }, label1 = { Text = "采样间隔" } };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                int d = Convert.ToInt32(dialog.getParam);//采样间隔
                var bm = new Bitmap(curBitmap);

                var p = new HiPerfTimer();
                p.Start();
                var bmp = Matlab.HorizontalSampling(bm, d);
                p.Stop();
                setResult(bmp, "横向采样 用时：" + p.Duration);
            }
        }

        //采样-竖向采样
        private void verticalSamplingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog { groupBox1 = { Text = "输入采样间隔(1/2/4/8/16)" }, label1 = { Text = "采样间隔" } };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                int d = Convert.ToInt32(dialog.getParam);//采样间隔
                var bm = new Bitmap(curBitmap);

                var p = new HiPerfTimer();
                p.Start();
                var bmp = Matlab.VerticalSampling(bm, d);
                p.Stop();
                setResult(bmp, "竖向采样 用时：" + p.Duration);
            }
        }

        //采样-横向二值采样
        private void horizontal2ValueSamplingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog { groupBox1 = { Text = "输入采样间隔(1/2/4/8/16)" }, label1 = { Text = "采样间隔" } };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                int d = Convert.ToInt32(dialog.getParam);//采样间隔
                var bm = new Bitmap(curBitmap);

                var p = new HiPerfTimer();
                p.Start();
                var bmp = Matlab.Horizontal2ValueSampling(bm, d);
                p.Stop();
                setResult(bmp, "横向二值采样 用时：" + p.Duration);
            }
        }

        //采样-竖向二值采样
        private void vertical2ValueSamplingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog { groupBox1 = { Text = "输入采样间隔(1/2/4/8/16)" }, label1 = { Text = "采样间隔" } };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                int d = Convert.ToInt32(dialog.getParam);//采样间隔
                var bm = new Bitmap(curBitmap);

                var p = new HiPerfTimer();
                p.Start();
                var bmp = Matlab.Vertical2ValueSampling(bm, d);
                p.Stop();
                setResult(bmp, "竖向二值采样 用时：" + p.Duration);
            }
        }

        //量化
        private void quantizationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog
                             {
                                 groupBox1 = { Text = "输入灰度级数(2/4/8/16/32/64/128/256)" },
                                 label1 = { Text = "灰度级数" }
                             };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var p = new HiPerfTimer();
                p.Start();
                int level = Convert.ToInt32(dialog.getParam);//灰度级数

                int grayLevel = 256 / level;
                var bm = new Bitmap(curBitmap);
                BitmapData data = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadWrite,
                                              PixelFormat.Format24bppRgb);

                unsafe
                {
                    var ptr = (byte*)data.Scan0;
                    for (int j = 0; j < ih; j++)
                    {
                        for (int i = 0; i < iw; i++)
                        {
                            int r = ptr[2];
                            int tem = r / grayLevel;
                            r = tem * grayLevel;

                            int g = ptr[1];
                            tem = g / grayLevel;
                            g = tem * grayLevel;

                            int b = ptr[0];
                            tem = b / grayLevel;
                            b = tem * grayLevel;

                            ptr[0] = (byte)b;
                            ptr[1] = (byte)g;
                            ptr[2] = (byte)r;
                            ptr += 3;
                        }
                        ptr += data.Stride - bm.Width * 3;
                    }
                }

                p.Stop();
                bm.UnlockBits(data);

                setResult(bm, "量化结果 用时：" + p.Duration);
            }
        }

        //图像转置
        private void transposeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var gs = new byte[ih, iw];
            for (int j = 0; j < iw; j++)
            {
                for (int i = 0; i < ih; i++)
                {
                    gs[i, j] = im[j, i];
                }
            }
            var obm = Common.ToBitmap(gs);
            setResult(obm, "图像转置");
        }

        //图像旋转
        private void retateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                var degree = Convert.ToDouble(dialog.getParam);
                var obm = ImageCorrect.RotateImg(bm, degree);
                setResult(obm, "图像旋转");
            }
        }

        //图片顺时针旋转90°
        private void Rotate90FlipNoneToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var obm = new Bitmap(curBitmap);
            obm = ImageOprationClass.ImageGoRound(obm);
            setResult(obm, "旋转结果");
        }

        //黑白反色
        private void invertToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            im = Matlab.Inverse(im);
            var obm = Common.ToBitmap(im);

            setResult(obm, "黑白反色");
        }

        //反色调(冷暖反色)
        private void reverseTonalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            var bm = new Bitmap(curBitmap);
            BitmapData data = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadWrite,
                                          PixelFormat.Format24bppRgb);
            int stride = data.Stride;

            var p = new HiPerfTimer();
            p.Start();

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();
                for (int j = 0; j < ih; j++)
                {
                    for (int i = 0; i < iw; i++)
                    {
                        int r = (ptr + j * stride + (i * 3))[2];
                        int g = (ptr + j * stride + (i * 3))[1];
                        int b = (ptr + j * stride + (i * 3))[0];

                        (ptr + j * stride + (i * 3))[2] = (byte)(255 - r);
                        (ptr + j * stride + (i * 3))[1] = (byte)(255 - g);
                        (ptr + j * stride + (i * 3))[0] = (byte)(255 - b);
                    }
                }
            }

            bm.UnlockBits(data);
            p.Stop();
            setResult(bm, "反色调 用时：" + p.Duration);
        }

        //横向投影（Y轴）
        private void horizontalProjectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            var gs = Projection.HorizontalProjection(im);

            var obm = Common.ToBitmap(gs);
            setResult(obm, "横向投影结果");
        }

        //纵向投影（X轴）
        private void verticalProjectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));

            var gs = Projection.VerticalProjection(im);

            var obm = Common.ToBitmap(gs);
            setResult(obm, "纵向投影结果");
        }

        //横向形心投影
        private void horizontalCenterProjectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            Matlab.ToGray(ref bm);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var obm = Common.ToBitmap(im);
            var centerxy = new int[2];
            Matlab.Center(obm, im, ref centerxy);

            var gs = Projection.HorizontalCenterProjection(im, centerxy[0]);
            var bt = Common.ToBitmap(gs);

            setResult(bt, "横向形心投影 形心坐标（" + centerxy[0] + "," + centerxy[1] + ")");
        }

        //纵向形心投影
        private void verticalCenterProjectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            Matlab.ToGray(ref bm);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var obm = Common.ToBitmap(im);
            var centerxy = new int[2];
            Matlab.Center(obm, im, ref centerxy);

            var gs = Matlab.VerticalCenterProjection(im, centerxy[1]);
            var bt = Common.ToBitmap(gs);

            setResult(bt, "纵向形心投影 形心坐标（" + centerxy[0] + "," + centerxy[1] + ")");
        }

        //横向投影归一化分析
        private void hToOneAnalysisToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog { Text = "归一化参数设置", label1 = { Text = "度量：" } };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                var mea = Convert.ToInt32(dialog.getParam.Trim());
                var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));

                //横向投影
                var gs = Projection.HorizontalProjection(im);
                //归一化处理
                gs = Matlab.Normalization(gs, mea);
                var obm = Common.ToBitmap(gs);
                setResult(obm, "横向投影归一化结果");
            }
        }

        //纵向投影归一化分析
        private void vToOneAnalysisToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog { Text = "归一化参数设置", label1 = { Text = "度量：" } };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                var mea = Convert.ToInt32(dialog.getParam.Trim());
                var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));

                //纵向投影
                var gs = Projection.VerticalProjection(im);
                //归一化处理
                gs = Matlab.Normalization(gs, mea, 1);

                var obm = Common.ToBitmap(gs);
                setResult(obm, "纵向投影归一化结果");
            }
        }

        //图像边缘扩张
        private void imageEageEnlargeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new WidthAndHeightEnlargeSetting();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var enWidth = Convert.ToInt32(dialog.GetEnWidth.Trim());
                var enHeight = Convert.ToInt32(dialog.GetEnHeight.Trim());
                var bm = new Bitmap(curBitmap);
                bm = Matlab.RectangleEageEnlarge(bm, enWidth, enHeight);
                setResult(bm, "图片放大效果");
            }
        }

        //图像文字连通
        private void fontConnectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
        }

        //图像缩放
        private void imageChangeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var w = 600;
            var h = 450;
            var rec = new Rectangle(0, 0, w, h);
            bm = Matlab.ImageChange(bm, rec);
            setResult(bm, "图像缩放");
        }

        #region 图像几何变换

        //C#内置方法-旋转变换
        private void cRotateToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var g = pictureBox2.CreateGraphics();
            g.TranslateTransform(200, 100);
            g.Clear(BackColor);
            g.DrawImage(bm, 0, 0);
            g.FillEllipse(new SolidBrush(Color.Red), -3, -3, 6, 6);
            g.DrawString("红点为旋转中心", Font, new SolidBrush(Color.Red), 0, -20);
            var dialog = new paramDialog
                             {
                                 Text = "旋转变换 旋转度数",
                                 groupBox1 = { Text = "旋转度数选择" },
                                 textBox1 = { Text = "30" },
                                 label1 = { Text = "旋转度数" }
                             };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var rotate = (float)Convert.ToDouble(dialog.getParam);
                g.RotateTransform(rotate);
                g.DrawImage(bm, 0, 0);
            }
        }

        //C#内置方法-缩放变换
        private void cZoomToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog
                             {
                                 Text = "缩放变换 参数选择",
                                 groupBox1 = { Text = "选择缩放比例参数（0.1-4.0）" },
                                 textBox1 = { Text = "1.5" },
                                 label1 = { Text = "缩放比例" }
                             };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                double p = Convert.ToDouble(dialog.getParam);
                var bm = new Bitmap(curBitmap);
                var g = pictureBox2.CreateGraphics();
                g.Clear(BackColor);
                g.ScaleTransform((float)p, (float)p, MatrixOrder.Append);
                g.DrawImage(bm, 0, 0);
            }
        }

        //C#内置方法-错切变换
        private void cShearingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new shearDialog();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var x1 = Convert.ToInt32(dialog.getX1);
                var x2 = Convert.ToInt32(dialog.getX2);
                var x3 = Convert.ToInt32(dialog.getX3);
                var y1 = Convert.ToInt32(dialog.getY1);
                var y2 = Convert.ToInt32(dialog.getY2);
                var y3 = Convert.ToInt32(dialog.getY3);

                var bm = new Bitmap(curBitmap);
                var g = pictureBox2.CreateGraphics();
                g.Clear(BackColor);

                var ip1 = new Point(x1, y1);
                var ip2 = new Point(x2, y2);
                var ip3 = new Point(x3, y3);

                Point[] destPara = { ip1, ip2, ip3 };

                g.DrawImage(bm, destPara);
            }
        }

        //C#内置方法-平移变换
        private void cOffsetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new translateDialog();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var x = Convert.ToInt32(dialog.getX);
                var y = Convert.ToInt32(dialog.getY);
                var bm = new Bitmap(curBitmap);
                var g = pictureBox2.CreateGraphics();
                g.Clear(BackColor);
                g.TranslateTransform(x, y, MatrixOrder.Append);
                g.DrawImage(bm, 0, 0);
            }
        }

        //仿射变换算法-旋转变换
        private void rotateToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var g = pictureBox2.CreateGraphics();
            g.Clear(BackColor);

            var owh = (int)(Math.Sqrt(iw * iw + ih * ih + 0.5));
            g.TranslateTransform((float)(owh - iw) / 2, (float)(owh - ih) / 2);
            g.DrawImage(bm, 0, 0);
            g.FillEllipse(new SolidBrush(Color.Red), iw / 2 - 3, ih / 2 - 3, 6, 6);
            g.DrawString("红点为旋转中心", Font, new SolidBrush(Color.Red), 0, 260);
            g.TranslateTransform((float)(iw - owh) / 2, (float)(ih - owh) / 2);
            var dialog = new paramDialog();
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var rotate = (float)Convert.ToInt32(dialog.getParam);
                var obm = ImageEnhancing.ImRotate(bm, rotate);
                g.DrawImage(obm, 0, 0);
                g.FillEllipse(new SolidBrush(Color.Red), owh / 2 - 3, owh / 2 - 3, 6, 6);

                setResult(obm, "旋转变换结果");
            }
        }

        //仿射变换算法-缩放变换
        private void zoomToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog
                             {
                                 groupBox1 = { Text = "选择缩放比例参数（0.1-4.0）" },
                                 Text = "缩放变换 参数选择",
                                 textBox1 = { Text = "1.5" },
                                 label1 = { Text = "缩放比例" }
                             };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                var p = Convert.ToDouble(dialog.getParam);

                var obm = ImageEnhancing.NearNeighbor(bm, p);
                setResult(obm, "缩放变换结果");
            }
        }

        //仿射变换算法-错切变换
        private void shearingToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog
                             {
                                 groupBox1 = { Text = "选择错切参数（0.1-0.8）" },
                                 textBox1 = { Text = "0.5" },
                                 label1 = { Text = "错切比例" },
                                 Text = "错切变换 参数选择"
                             };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                double p = Convert.ToDouble(dialog.getParam);
                var obm = ImageEnhancing.ShearTest(bm, p);
                setResult(obm, "错切变换结果");
            }
        }

        //仿射变换算法-平移变换
        private void offsetToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new translateDialog();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                var x = Convert.ToInt32(dialog.getX);
                var y = Convert.ToInt32(dialog.getY);

                var obm = ImageEnhancing.TranslateTest(bm, x, y);

                setResult(obm, "平移变换结果");
            }
        }

        //图像插值-双线性插值
        private void biLiearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog
                             {
                                 Text = "双线性插值 参数选择",
                                 groupBox1 = { Text = "选择缩放比例参数（0.1-4.0）" },
                                 textBox1 = { Text = "1.5" },
                                 label1 = { Text = "缩放比例" }
                             };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                double p = Convert.ToDouble(dialog.getParam);

                var obm = ImageEnhancing.BiLinear(bm, p);
                setResult(obm, "双线性插值结果");
            }
        }

        //图像插值-三次卷积插值
        private void scaleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var dialog = new paramDialog
                             {
                                 Text = "三次卷积插值 参数选择",
                                 groupBox1 = { Text = "选择缩放比例参数（0.1-4.0）" },
                                 textBox1 = { Text = "1.5" },
                                 label1 = { Text = "缩放比例" }
                             };

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var bm = new Bitmap(curBitmap);
                double p = Convert.ToDouble(dialog.getParam);

                var obm = ImageEnhancing.Scale(bm, 0, 0, iw, p, p);
                setResult(obm, "三次卷积插值结果");
            }
        }

        #endregion

        #endregion

        #region 影像识别

        #region 思考步骤

        //计算偏向角度
        private void calculationDeviationAngleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw);//找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih);//找竖线

            if (hLines.Count > 0 || vLines.Count > 0)
            {
                var degree = ImageCorrect.GetDegree2(hLines, vLines);
                var d = Math.Round(degree / Math.PI * 180, 2);
                MessageBox.Show(d.ToString(), "影像偏向角度");
            }
        }

        //纠偏
        private void rectificationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            var bm = new Bitmap(curBitmap);
            var obm = ImageCorrect.ImageRectification(bm);
            setResult(obm, "纠偏结果");
        }

        //黑色块画直线
        private void drawingLineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //GetCurrentImage();
            //var bm = new Bitmap(curBitmap);
            //var bms = Matlab.thresh(bm, iw, ih, Matlab.getThreshold(bm));
            ////横向二值采样（采样率 = 宽度/80，约等于32）
            //bms = Matlab.Horizontal2ValueSampling(bms, iw / 80);
            //var im = Common.toBinary(bms, Matlab.getThreshold(bm));
            //var horizontalLines = Matlab.HorizontalLine(im, iw / 3, iw / 80 - 2);
            //var verticalLines = Matlab.VerticalLine(im, ih, 64);

            //var data = bms.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            //unsafe
            //{
            //    var ptr = (byte*)data.Scan0.ToPointer();
            //    foreach (var horizontalLine in horizontalLines)
            //    {
            //        for (int i = horizontalLine.B_Min; i <= horizontalLine.B_Max; i++)
            //        {
            //            var p = (ptr + horizontalLine.A * iw * 3 + (data.Stride - iw * 3) * horizontalLine.A + i * 3);
            //            p[0] = 0;
            //            p[1] = 0;
            //            p[2] = 255;
            //        }
            //    }
            //    foreach (var verticalLine in verticalLines)
            //    {
            //        for (int j = verticalLine.B_Min; j < verticalLine.B_Max; j++)
            //        {
            //            var p = (ptr + j * iw * 3 + (data.Stride - iw * 3) * j + verticalLine.A * 3);
            //            p[0] = 0;
            //            p[1] = 0;
            //            p[2] = 255;
            //        }
            //    }
            //}

            //bms.UnlockBits(data);

            //SetResult(bms, "查找连线结果");

            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            Matlab.ToGray(ref bm);

            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var obm = Common.ToBitmap(im);
            im = Common.ToBinary(obm, Matlab.GetThreshold(obm));
            im = Matlab.Horizontal2ValueSampling(im, 32);
            obm = Common.ToBitmap(im);
            var lines = ImageAnalysis.FindHorizontalLines(im, 33, 31, iw);

            var data = obm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();
                foreach (var line in lines)
                {
                    for (int i = line.B_Min; i <= line.B_Max; i++)
                    {
                        var p = ptr + line.A * data.Stride + i * 3;
                        p[0] = 0;
                        p[1] = 0;
                        p[2] = 255;
                    }
                }
            }

            obm.UnlockBits(data);

            setResult(obm, "找线结果");
        }

        //得到矩形区域
        private void getRectangleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);

            //二值化影像
            var bms = Matlab.Thresh(bm, iw, ih, Matlab.GetThreshold(bm));
            var binaryBm = new Bitmap(bms);

            var pt = new HiPerfTimer();
            pt.Start();

            //横向二值采样（采样率 = 宽度/80，约等于32）
            bms = Matlab.Horizontal2ValueSampling(bms, iw / 80);

            //将采样的影像二值化
            var im = Common.ToBinary(bms, Matlab.GetThreshold(bm));
            //im = Matlab.Horizontal2ValueSampling(im, 32);

            //找横向分隔区
            bms = ImageAnalysis.FindTransverseSpace(bms, im, 0.2f);

            //找左边竖线
            bms = ImageAnalysis.FindLeftLines(bms, im, 0.1f);

            setResult(bms, "矩形区"); return;

            // 红色区域涂白，得到内容矩形阵图
            bms = ImageAnalysis.Getfield(bms);

            //找到每个矩形区
            var rs = ImageAnalysis.FindRectangle(bms);

            //将每个矩形区域保存为 tif 格式的图片
            ImageAnalysis.SaveImageToTif(new Bitmap(binaryBm), rs, ConfigOpration.SavePath);

            setResult(bms, "矩形区");
        }

        //get content area from image
        private void getContentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            //To gray image
            Matlab.ToGray(ref bm);
            //get two-value matrix
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            //get two-value image
            var imProY = Projection.HorizontalProjection(im);
            im = Matlab.HorizontalProjectionAnalysis(im, imProY);
            var imProX = Projection.VerticalProjection(im);
            im = Matlab.VerticalProjectionAnalysis(im, imProX);
            Bitmap obm = Common.ToBitmap(im);

            setResult(obm, "找内容区");
        }

        //analysis lines in image
        private void linesAnalysisToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = new Bitmap(iw, ih);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw);//找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih);//找竖线
            var data = obm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();

                for (int i = 0; i < iw; i++)
                {
                    for (int j = 0; j < ih; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        _ptr[2] = 255;
                        _ptr[1] = 255;
                        _ptr[0] = 255;
                    }
                }

                //画横线
                foreach (var line in hLines)
                {
                    for (int i = line.B_Min; i <= line.B_Max; i++)
                    {
                        var _ptr = ptr + line.A * data.Stride + i * 3;
                        _ptr[2] = 0;
                        _ptr[1] = 0;
                        _ptr[0] = 0;
                    }
                }

                //画竖线
                foreach (var line in vLines)
                {
                    for (int j = line.B_Min; j <= line.B_Max; j++)
                    {
                        var _ptr = ptr + j * data.Stride + line.A * 3;
                        _ptr[2] = 0;
                        _ptr[1] = 0;
                        _ptr[0] = 0;
                    }
                }
            }

            obm.UnlockBits(data);
            setResult(obm, "找线结果");
        }

        //直线细化
        private void htinnerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = new Bitmap(iw, ih);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw);//找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih);//找竖线
            var data = obm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            List<Line> tinnerHLines = ImageAnalysis.GetTinnerLines(hLines);//将所有横线细化
            List<Line> tinnerVLines = ImageAnalysis.GetTinnerLines(vLines);//将所有竖线细化

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();

                for (int i = 0; i < iw; i++)
                {
                    for (int j = 0; j < ih; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        _ptr[2] = 255;
                        _ptr[1] = 255;
                        _ptr[0] = 255;
                    }
                }

                //画出细化后的横线
                foreach (var line in tinnerHLines)
                {

                    for (int i = line.B_Min; i <= line.B_Max; i++)
                    {
                        var _ptr = ptr + line.A * data.Stride + i * 3;
                        _ptr[2] = 0;
                        _ptr[1] = 0;
                        _ptr[0] = 0;
                    }
                }

                //画出细化后的竖线
                foreach (var line in tinnerVLines)
                {
                    for (int j = line.B_Min; j <= line.B_Max; j++)
                    {
                        var _ptr = ptr + j * data.Stride + line.A * 3;
                        _ptr[2] = 0;
                        _ptr[1] = 0;
                        _ptr[0] = 0;
                    }
                }
            }

            obm.UnlockBits(data);
            setResult(obm, "细化结果");
        }

        //去掉噪音线
        private void deleteNoiseLineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = new Bitmap(iw, ih);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw);//找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih);//找竖线
            var data = obm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            List<Line> tinnerHLines = ImageAnalysis.GetTinnerLines(hLines);//将所有横线细化
            List<Line> tinnerVLines = ImageAnalysis.GetTinnerLines(vLines);//将所有竖线细化

            //去噪音线
            tinnerHLines = ImageAnalysis.DeleteNoiseLines(tinnerHLines, tinnerVLines, 28, iw / 4);
            tinnerVLines = ImageAnalysis.DeleteNoiseLines(tinnerVLines, tinnerHLines, 50, ih / 4);
            //去边界线
            if (tinnerHLines.Count > 1 && tinnerVLines.Count > 1)
            {
                ImageAnalysis.DeleteEdgeLines(ref tinnerHLines, ref tinnerVLines, iw, ih);
            }

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();

                for (int i = 0; i < iw; i++)
                {
                    for (int j = 0; j < ih; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        _ptr[2] = 255;
                        _ptr[1] = 255;
                        _ptr[0] = 255;
                    }
                }

                //画出细化后的横线
                foreach (var line in tinnerHLines)
                {
                    for (int i = line.B_Min; i <= line.B_Max; i++)
                    {
                        var _ptr = ptr + line.A * data.Stride + i * 3;
                        _ptr[2] = 0;
                        _ptr[1] = 0;
                        _ptr[0] = 0;
                    }
                }

                //画出细化后的竖线
                foreach (var line in tinnerVLines)
                {
                    for (int j = line.B_Min; j <= line.B_Max; j++)
                    {
                        var _ptr = ptr + j * data.Stride + line.A * 3;
                        _ptr[2] = 0;
                        _ptr[1] = 0;
                        _ptr[0] = 0;
                    }
                }
            }

            obm.UnlockBits(data);
            setResult(obm, "去噪音线结果");
        }

        //直线补全
        private void linesCompleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = new Bitmap(iw, ih);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw);//找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih);//找竖线
            List<Line> tinnerHLines = ImageAnalysis.GetTinnerLines(hLines);//将所有横线细化
            List<Line> tinnerVLines = ImageAnalysis.GetTinnerLines(vLines);//将所有竖线细化

            //去噪音线
            tinnerHLines = ImageAnalysis.DeleteNoiseLines(tinnerHLines, tinnerVLines, 28, iw / 4);
            tinnerVLines = ImageAnalysis.DeleteNoiseLines(tinnerVLines, tinnerHLines, 50, ih / 4);
            //去边界线
            ImageAnalysis.DeleteEdgeLines(ref tinnerHLines, ref tinnerVLines, iw, ih);
            //直线补全
            ImageAnalysis.LinesComplete(ref tinnerHLines, ref tinnerVLines, iw, ih, 100);

            var data = obm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();

                for (int i = 0; i < iw; i++)
                {
                    for (int j = 0; j < ih; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        _ptr[2] = 255;
                        _ptr[1] = 255;
                        _ptr[0] = 255;
                    }
                }

                //画出细化后的横线
                foreach (var line in tinnerHLines)
                {
                    for (int i = line.B_Min; i <= line.B_Max; i++)
                    {
                        var _ptr = ptr + line.A * data.Stride + i * 3;
                        _ptr[2] = 0;
                        _ptr[1] = 0;
                        _ptr[0] = 0;
                    }
                }

                //画出细化后的竖线
                foreach (var line in tinnerVLines)
                {
                    for (int j = line.B_Min; j <= line.B_Max; j++)
                    {
                        var _ptr = ptr + j * data.Stride + line.A * 3;
                        _ptr[2] = 0;
                        _ptr[1] = 0;
                        _ptr[0] = 0;
                    }
                }
            }

            obm.UnlockBits(data);
            setResult(obm, "直线补全");
        }

        //直线修正
        private void correctLineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = new Bitmap(iw, ih);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw);//找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih);//找竖线
            var data = obm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            List<Line> tinnerHLines = ImageAnalysis.GetTinnerLines(hLines);//将所有横线细化
            List<Line> tinnerVLines = ImageAnalysis.GetTinnerLines(vLines);//将所有竖线细化

            //去噪音线
            tinnerHLines = ImageAnalysis.DeleteNoiseLines(tinnerHLines, tinnerVLines, 28, iw / 4);
            tinnerVLines = ImageAnalysis.DeleteNoiseLines(tinnerVLines, tinnerHLines, 50, ih / 4);
            //去边界线
            ImageAnalysis.DeleteEdgeLines(ref tinnerHLines, ref tinnerVLines, iw, ih);
            //直线补全
            //ImageAnalysis.LinesComplete(ref tinnerHLines, ref tinnerVLines, iw, ih, 100);
            //直线修正
            ImageAnalysis.CorrectLines(ref tinnerHLines, ref tinnerVLines, 50);

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();

                for (int i = 0; i < iw; i++)
                {
                    for (int j = 0; j < ih; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        _ptr[2] = 255;
                        _ptr[1] = 255;
                        _ptr[0] = 255;
                    }
                }

                //画出细化后的横线
                foreach (var line in tinnerHLines)
                {
                    for (int i = line.B_Min; i <= line.B_Max; i++)
                    {
                        var _ptr = ptr + line.A * data.Stride + i * 3;
                        _ptr[2] = 0;
                        _ptr[1] = 0;
                        _ptr[0] = 0;
                    }
                }

                //画出细化后的竖线
                foreach (var line in tinnerVLines)
                {
                    for (int j = line.B_Min; j <= line.B_Max; j++)
                    {
                        var _ptr = ptr + j * data.Stride + line.A * 3;
                        _ptr[2] = 0;
                        _ptr[1] = 0;
                        _ptr[0] = 0;
                    }
                }
            }

            obm.UnlockBits(data);
            setResult(obm, "修正直线结果");
        }

        //找线的交点
        private void findLinesNodesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            var obm = new Bitmap(iw, ih);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw);//找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih);//找竖线
            var data = obm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            List<Line> tinnerHLines = ImageAnalysis.GetTinnerLines(hLines);//将所有横线细化
            List<Line> tinnerVLines = ImageAnalysis.GetTinnerLines(vLines);//将所有竖线细化

            //去噪音线
            tinnerHLines = ImageAnalysis.DeleteNoiseLines(tinnerHLines, tinnerVLines, 28, iw / 4);
            tinnerVLines = ImageAnalysis.DeleteNoiseLines(tinnerVLines, tinnerHLines, 50, ih / 4);
            //去边界线
            ImageAnalysis.DeleteEdgeLines(ref tinnerHLines, ref tinnerVLines, iw, ih);
            //直线修正
            ImageAnalysis.CorrectLines(ref tinnerHLines, ref tinnerVLines, 50);
            //找直线交点
            var nodeList = ImageAnalysis.GetLinesNodes(tinnerHLines, tinnerVLines);

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();

                for (int i = 0; i < iw; i++)
                {
                    for (int j = 0; j < ih; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        _ptr[2] = 255;
                        _ptr[1] = 255;
                        _ptr[0] = 255;
                    }
                }

                //画出细化后的横线
                foreach (var line in tinnerHLines)
                {
                    for (int i = line.B_Min; i <= line.B_Max; i++)
                    {
                        var _ptr = ptr + line.A * data.Stride + i * 3;
                        _ptr[2] = 0;
                        _ptr[1] = 0;
                        _ptr[0] = 0;
                    }
                }

                //画出细化后的竖线
                foreach (var line in tinnerVLines)
                {
                    for (int j = line.B_Min; j <= line.B_Max; j++)
                    {
                        var _ptr = ptr + j * data.Stride + line.A * 3;
                        _ptr[2] = 0;
                        _ptr[1] = 0;
                        _ptr[0] = 0;
                    }
                }

                if (nodeList.Count > 0)
                {
                    foreach (var node in nodeList)
                    {
                        for (int i = -3; i < 4; i++)
                        {
                            for (int j = -3; j < 4; j++)
                            {
                                var _ptr = ptr + (node[1] + j) * data.Stride + (node[0] + i) * 3;
                                _ptr[2] = 255;
                                _ptr[1] = 0;
                                _ptr[0] = 0;
                            }
                        }
                    }
                }
            }

            obm.UnlockBits(data);
            setResult(obm, "显示交点");
        }

        //分析直线找内容区
        private void analysisLinesFindContentAreaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            List<Line> tinnerHLines;
            List<Line> tinnerVLines;
            var newBitmap = ImageAnalysis.GetModelLines(bm, out tinnerHLines, out tinnerVLines);
            //只针对带框或表格类型影像
            var contentRec = ImageAnalysis.AnalysisLinesFindContentArea(tinnerHLines, tinnerVLines, newBitmap.Width, newBitmap.Height);
            var obm = new Bitmap(contentRec.Width, contentRec.Height);
            var data = newBitmap.LockBits(contentRec, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            var dataObm = obm.LockBits(new Rectangle(0, 0, contentRec.Width, contentRec.Height), ImageLockMode.WriteOnly,
                                       PixelFormat.Format24bppRgb);

            unsafe
            {
                var ptr1 = (byte*)data.Scan0.ToPointer();
                var ptr2 = (byte*)dataObm.Scan0.ToPointer();

                for (int j = 0; j < contentRec.Height; j++)
                {
                    for (int i = 0; i < contentRec.Width; i++)
                    {
                        var _ptr1 = ptr1 + j * data.Stride + i * 3;
                        var _ptr2 = ptr2 + j * dataObm.Stride + i * 3;
                        _ptr2[2] = _ptr1[2];
                        _ptr2[1] = _ptr1[1];
                        _ptr2[0] = _ptr1[0];
                    }
                }
            }

            obm.UnlockBits(dataObm);
            newBitmap.UnlockBits(data);

            setResult(obm, "分析直线找内容区");
        }

        #endregion

        //OCR
        private void oCRToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            if (!Directory.Exists("Images"))
            {
                Directory.CreateDirectory("Images");
            }
            var _path = "Images\\" + label1.Text.Substring(0, label1.Text.LastIndexOf('.')) + ".tif";
            bm.Save(_path, ImageFormat.Tiff);
            string str = "";
            OCR.ImageToOCR(_path, ref str);
            if (!String.IsNullOrEmpty(str))
            {
                File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "OCRText.txt", str);
                DialogResult msgBoxResult = MessageBox.Show(
                        "图像OCR处理完成，请查看DEBUG下日志文件夹。\r\n是否打开该目录？",//对话框的显示内容
                        "信息提示",//对话框的标题
                        MessageBoxButtons.YesNo,//定义对话框的按钮，这里定义了YSE和NO两个按钮     
                        MessageBoxIcon.Information, //定义对话框内的图表式样
                        MessageBoxDefaultButton.Button1//定义对话框的按钮式样
                        );
                if (msgBoxResult == DialogResult.Yes)
                {
                    System.Diagnostics.Process.Start("explorer.exe", AppDomain.CurrentDomain.BaseDirectory + "OCRText.txt");
                    MessageBox.Show("识别完成，查看DEBUG目录下的OCRText.txt", "Message");
                }
            }
            else
            {
                MessageBox.Show("未能识别。", "Message");
            }
        }

        //矩形特征分析法
        private void rectangularAnalysisToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            /*
             * 计时器开始
             */
            var pt = new HiPerfTimer();
            pt.Start();

            var bm = new Bitmap(curBitmap);

            //二值化影像
            var bms = Matlab.Thresh(bm, iw, ih, Matlab.GetThreshold(bm));
            var binaryBm = new Bitmap(bms);

            //横向二值采样（采样率 = 宽度/80，约等于32）
            bms = Matlab.Horizontal2ValueSampling(bms, iw / 80);

            //将采样的影像二值化
            var im = Common.ToBinary(bms, Matlab.GetThreshold(bm));

            //找左边竖线
            bms = ImageAnalysis.FindLeftLines(bms, im, 0.1f);

            //找横向分隔区
            bms = ImageAnalysis.FindTransverseSpace(bms, im, 0.2f);

            // 红色区域涂白，得到内容矩形阵图
            bms = ImageAnalysis.Getfield(bms);

            //找到每个矩形区
            var rs = ImageAnalysis.FindRectangle(bms);

            //将每个矩形区域保存为 tif 格式的图片
            ImageAnalysis.SaveImageToTifForListImage(new Bitmap(binaryBm), rs, ConfigOpration.SavePath);

            //OCR识别找药品
            var ms = new List<Medicine>();
            for (int i = 1; i <= rs.Count; i++)
            {
                var _path = ConfigOpration.SavePath + i + ".tif";
                var str = "";

                if (OCR.ImageToOCR(_path, ref str))
                {
                    var matchClass = new MatchMedicine();
                    //初始化数据
                    if (MatchMedicine.AllMedicines == null)
                    {
                        MatchMedicine.AllMedicines = matchClass.SelectMedicine();
                    }
                    allMedicine = MatchMedicine.AllMedicines;
                    string matchtMedicine = string.Empty;

                    //获取与字符串符合的药品
                    var hasMatch = matchClass.SimilarMatching(str, ref matchtMedicine);

                    if (hasMatch)
                    {
                        var m = new Medicine();
                        m.X = rs[i - 1].X;
                        m.Y = rs[i - 1].Y;
                        m.medicineName = str + "\r\n" + "【数据库匹配】：" + matchtMedicine + "\r\n";
                        ms.Add(m);
                    }
                }
            }

            var cs = AnalysisMedichine(ms);
            var strM = "";
            foreach (var c in cs)
            {
                for (int i = 0; i < c.Value.Count; i++)
                {
                    strM += c.Value[i].medicineName + "\r\n";
                }
                strM += "\r\n";
            }

            /*
             * 计时器结束
             */
            pt.Stop();

            //写入日志
            File.WriteAllText(ConfigOpration.SavePath + "Log.txt", strM);
            MessageBox.Show("信息已写入日志，共用时：" + pt.Duration + "秒", "Message");
        }

        //通用药品区分析
        private void commonAnalysisToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);
            List<Line> tinnerHLines;
            List<Line> tinnerVLines;
            var newBitmap = ImageAnalysis.GetModelLines(bm, out tinnerHLines, out tinnerVLines);

            //根据直线分析影像类型，并返回药品区域
            var contentRectangle = new Rectangle(0, 0, iw, ih);
            var imageType = ImageAnalysis.AnalysicImageClass(tinnerHLines, tinnerVLines, iw, ih, ref contentRectangle);

            //截取药品区域
            try
            {
                var newBm = Common.GetBitmap(newBitmap, contentRectangle);
                setResult(newBm, "药品区分析【" + imageType + "】");
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "异常提示");
            }
        }

        #region 上海发票影像识别

        //上海发票分行识别
        private void shangHaiRowOCRToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            /*
             * 计时器开始
             */
            var pt = new HiPerfTimer();
            pt.Start();

            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(ref bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw);//找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih);//找竖线
            var hLinesCount = hLines.Count;
            var vLinesCount = vLines.Count;
            var tinnerHLines = new List<Line>();
            var tinnerVLines = new List<Line>();

            if (hLinesCount > 0)
            {
                //将所有横线细化
                tinnerHLines = ImageAnalysis.GetTinnerLines(hLines);
                //去噪音线
                tinnerHLines = ImageAnalysis.DeleteNoiseLines(tinnerHLines, tinnerVLines, 28, iw / 4);
            }

            if (vLinesCount > 0)
            {
                //将所有竖线细化
                tinnerVLines = ImageAnalysis.GetTinnerLines(vLines);
                //去噪音线
                tinnerVLines = ImageAnalysis.DeleteNoiseLines(tinnerVLines, tinnerHLines, 50, ih / 4);
            }

            if (hLinesCount > 0 && vLinesCount > 0)
            {
                //去边界线
                ImageAnalysis.DeleteEdgeLines(ref tinnerHLines, ref tinnerVLines, iw, ih);
                //直线修正
                ImageAnalysis.CorrectLines(ref tinnerHLines, ref tinnerVLines, 50);
            }

            var contentRectangle = new Rectangle(0, 0, iw, ih);
            var imageType = ImageAnalysis.AnalysicImageClass(tinnerHLines, tinnerVLines, iw, ih, ref contentRectangle);
            var obm = new Bitmap(contentRectangle.Width, contentRectangle.Height);
            var data = bm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            var dataObm = obm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
            //提取药品内容区
            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();
                var ptr2 = (byte*)dataObm.Scan0.ToPointer();

                for (int i = contentRectangle.X; i < contentRectangle.Width + contentRectangle.X; i++)
                {
                    for (int j = contentRectangle.Y; j < contentRectangle.Height + contentRectangle.Y; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        var _ptr2 = ptr2 + (j - contentRectangle.Y) * dataObm.Stride + (i - contentRectangle.X) * 3;
                        _ptr2[2] = _ptr[2];
                        _ptr2[1] = _ptr[1];
                        _ptr2[0] = _ptr[0];
                    }
                }
            }

            bm.UnlockBits(data);
            obm.UnlockBits(dataObm);

            if (imageType == ImageType.Bill)
            {
                var gs = Common.ToBinary(obm, Matlab.GetThreshold(obm));
                var pgs = Projection.HorizontalProjection(gs);
                var listRectangleRow = ImageAnalysis.GetRowArea(pgs, contentRectangle.Width, contentRectangle.Height, 50, 20);

                var str = "";
                //将每个矩形区域保存为 tif 格式的图片
                ImageAnalysis.SaveImageToTif(new Bitmap(obm), listRectangleRow, ConfigOpration.SavePath);

                for (int i = 1; i <= listRectangleRow.Count; i++)
                {
                    var _pathImg = ConfigOpration.SavePath + i + ".tif";
                    var s = "";
                    if (OCR.ImageToOCR(_pathImg, ref s))
                    {
                        str += s + "\r\n";
                    }
                }

                var dataNew = obm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

                unsafe
                {
                    var p = (byte*)dataNew.Scan0.ToPointer();

                    foreach (var rectangle in listRectangleRow)
                    {
                        for (int i = rectangle.X; i < rectangle.X + rectangle.Width; i++)
                        {
                            var ju = rectangle.Y;
                            var jd = rectangle.Y + rectangle.Height;

                            var _pu = p + ju * dataNew.Stride + i * 3;
                            var _pd = p + jd * dataNew.Stride + i * 3;
                            _pu[2] = _pd[2] = 255;
                            _pu[1] = _pd[1] = 0;
                            _pu[0] = _pd[0] = 0;
                        }

                        for (int j = rectangle.Y; j < rectangle.Y + rectangle.Height; j++)
                        {
                            var il = rectangle.X;
                            var ir = rectangle.X + rectangle.Width;

                            var _pl = p + j * dataNew.Stride + il * 3;
                            var _pr = p + j * dataNew.Stride + ir * 3;
                            _pl[2] = _pr[2] = 255;
                            _pl[1] = _pr[1] = 0;
                            _pl[0] = _pr[0] = 0;
                        }
                    }
                }

                obm.UnlockBits(dataNew);

                /*
                 * 计时器结束
                 */
                pt.Stop();

                setResult(obm, "画矩形 用时：" + pt.Duration);

                MessageBox.Show(str, "药品名称");
            }
            else
            {
                MessageBox.Show("不是上海发票影像", "信息提示");
            }
        }

        //上海发票分矩形识别-断点法
        private void shangHaiBreakpointToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            /*
             * 计时器开始
             */
            var pt = new HiPerfTimer();
            pt.Start();

            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(ref bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw); //找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih); //找竖线
            var hLinesCount = hLines.Count;
            var vLinesCount = vLines.Count;
            var tinnerHLines = new List<Line>();
            var tinnerVLines = new List<Line>();

            if (hLinesCount > 0)
            {
                //将所有横线细化
                tinnerHLines = ImageAnalysis.GetTinnerLines(hLines);
                //去噪音线
                tinnerHLines = ImageAnalysis.DeleteNoiseLines(tinnerHLines, tinnerVLines, 28, iw / 4);
            }

            if (vLinesCount > 0)
            {
                //将所有竖线细化
                tinnerVLines = ImageAnalysis.GetTinnerLines(vLines);
                //去噪音线
                tinnerVLines = ImageAnalysis.DeleteNoiseLines(tinnerVLines, tinnerHLines, 50, ih / 4);
            }

            if (hLinesCount > 0 && vLinesCount > 0)
            {

                //去边界线
                ImageAnalysis.DeleteEdgeLines(ref tinnerHLines, ref tinnerVLines, iw, ih);
                //直线修正
                ImageAnalysis.CorrectLines(ref tinnerHLines, ref tinnerVLines, 50);
            }

            var contentRectangle = new Rectangle(0, 0, iw, ih);
            var imageType = ImageAnalysis.AnalysicImageClass(tinnerHLines, tinnerVLines, iw, ih, ref contentRectangle);
            var obm = new Bitmap(contentRectangle.Width, contentRectangle.Height);
            var data = bm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            var dataObm = obm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height),
                                       ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
            //提取药品内容区
            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();
                var ptr2 = (byte*)dataObm.Scan0.ToPointer();

                for (int i = contentRectangle.X; i < contentRectangle.Width + contentRectangle.X; i++)
                {
                    for (int j = contentRectangle.Y; j < contentRectangle.Height + contentRectangle.Y; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        var _ptr2 = ptr2 + (j - contentRectangle.Y) * dataObm.Stride + (i - contentRectangle.X) * 3;
                        _ptr2[2] = _ptr[2];
                        _ptr2[1] = _ptr[1];
                        _ptr2[0] = _ptr[0];
                    }
                }
            }

            bm.UnlockBits(data);
            obm.UnlockBits(dataObm);

            if (imageType == ImageType.Bill)
            {
                var gs = Common.ToBinary(obm, Matlab.GetThreshold(obm));
                var pgs = Projection.HorizontalProjection(gs);
                var listRectangleRow = ImageAnalysis.GetRowArea(pgs, contentRectangle.Width, contentRectangle.Height, 50,
                                                                20);
                var listRectangles = ImageAnalysis.AnalysisColumn1(gs, listRectangleRow);

                var str = "";
                foreach (var rectangles in listRectangles)
                {
                    var _path = ConfigOpration.SavePath + listRectangles.IndexOf(rectangles) + "\\";
                    if (!Directory.Exists(_path))
                    {
                        Directory.CreateDirectory(_path);
                    }
                    //将每个矩形区域保存为 tif 格式的图片
                    ImageAnalysis.SaveImageToTif(new Bitmap(obm), rectangles, _path);

                    for (int i = 1; i <= rectangles.Count; i++)
                    {
                        var _pathImg = _path + i + ".tif";
                        var s = "";
                        if (OCR.ImageToOCR(_pathImg, ref s))
                        {
                            str += s + "\r\n";
                        }
                    }
                }

                var dataNew = obm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height),
                                           ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

                unsafe
                {
                    var p = (byte*)dataNew.Scan0.ToPointer();

                    foreach (var rectangles in listRectangles)
                    {
                        foreach (var rectangle in rectangles)
                        {
                            for (int i = rectangle.X; i < rectangle.X + rectangle.Width; i++)
                            {
                                var ju = rectangle.Y;
                                var jd = rectangle.Y + rectangle.Height;

                                var _pu = p + ju * dataNew.Stride + i * 3;
                                var _pd = p + jd * dataNew.Stride + i * 3;
                                _pu[2] = _pd[2] = 255;
                                _pu[1] = _pd[1] = 0;
                                _pu[0] = _pd[0] = 0;
                            }

                            for (int j = rectangle.Y; j < rectangle.Y + rectangle.Height; j++)
                            {
                                var il = rectangle.X;
                                var ir = rectangle.X + rectangle.Width;

                                var _pl = p + j * dataNew.Stride + il * 3;
                                var _pr = p + j * dataNew.Stride + ir * 3;
                                _pl[2] = _pr[2] = 255;
                                _pl[1] = _pr[1] = 0;
                                _pl[0] = _pr[0] = 0;
                            }
                        }
                    }
                }

                obm.UnlockBits(dataNew);

                /*
                 * 计时器结束
                 */
                pt.Stop();

                setResult(obm, "画矩形 用时：" + pt.Duration);

                MessageBox.Show(str, "药品名称");
            }
            else
            {
                MessageBox.Show("不是上海发票影像", "信息提示");
            }
        }

        //上海发票分矩形识别-分段法
        private void shangHaiRectangleOCRToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            /*
             * 计时器开始
             */
            var pt = new HiPerfTimer();
            pt.Start();

            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(ref bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw); //找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih); //找竖线
            var hLinesCount = hLines.Count;
            var vLinesCount = vLines.Count;
            var tinnerHLines = new List<Line>();
            var tinnerVLines = new List<Line>();

            if (hLinesCount > 0)
            {
                //将所有横线细化
                tinnerHLines = ImageAnalysis.GetTinnerLines(hLines);
                //去噪音线
                tinnerHLines = ImageAnalysis.DeleteNoiseLines(tinnerHLines, tinnerVLines, 28, iw / 4);
            }

            if (vLinesCount > 0)
            {
                //将所有竖线细化
                tinnerVLines = ImageAnalysis.GetTinnerLines(vLines);
                //去噪音线
                tinnerVLines = ImageAnalysis.DeleteNoiseLines(tinnerVLines, tinnerHLines, 50, ih / 4);
            }

            if (hLinesCount > 0 && vLinesCount > 0)
            {

                //去边界线
                ImageAnalysis.DeleteEdgeLines(ref tinnerHLines, ref tinnerVLines, iw, ih);
                //直线修正
                ImageAnalysis.CorrectLines(ref tinnerHLines, ref tinnerVLines, 50);
            }

            var contentRectangle = new Rectangle(0, 0, iw, ih);
            var imageType = ImageAnalysis.AnalysicImageClass(tinnerHLines, tinnerVLines, iw, ih, ref contentRectangle);
            var obm = new Bitmap(contentRectangle.Width, contentRectangle.Height);
            var data = bm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            var dataObm = obm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height),
                                       ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
            //提取药品内容区
            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();
                var ptr2 = (byte*)dataObm.Scan0.ToPointer();

                for (int i = contentRectangle.X; i < contentRectangle.Width + contentRectangle.X; i++)
                {
                    for (int j = contentRectangle.Y; j < contentRectangle.Height + contentRectangle.Y; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        var _ptr2 = ptr2 + (j - contentRectangle.Y) * dataObm.Stride + (i - contentRectangle.X) * 3;
                        _ptr2[2] = _ptr[2];
                        _ptr2[1] = _ptr[1];
                        _ptr2[0] = _ptr[0];
                    }
                }
            }

            bm.UnlockBits(data);
            obm.UnlockBits(dataObm);

            if (imageType == ImageType.Bill)
            {
                var gs = Common.ToBinary(obm, Matlab.GetThreshold(obm));
                var pgs = Projection.HorizontalProjection(gs);
                var listRectangleRow = ImageAnalysis.GetRowArea(pgs, contentRectangle.Width, contentRectangle.Height, 50,
                                                                20);
                var listRectangles = ImageAnalysis.AnalysisColumn2(gs, listRectangleRow);

                var str = "";
                foreach (var rectangles in listRectangles)
                {
                    var _path = ConfigOpration.SavePath + listRectangles.IndexOf(rectangles) + "\\";
                    if (!Directory.Exists(_path))
                    {
                        Directory.CreateDirectory(_path);
                    }
                    //将每个矩形区域保存为 tif 格式的图片
                    ImageAnalysis.SaveImageToTif(new Bitmap(obm), rectangles, _path);

                    for (int i = 1; i <= rectangles.Count; i++)
                    {
                        var _pathImg = _path + i + ".tif";
                        var s = "";
                        if (OCR.ImageToOCR(_pathImg, ref s))
                        {
                            str += s + "\r\n";
                        }
                    }
                }

                var dataNew = obm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height),
                                           ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

                unsafe
                {
                    var p = (byte*)dataNew.Scan0.ToPointer();

                    foreach (var rectangles in listRectangles)
                    {
                        foreach (var rectangle in rectangles)
                        {
                            for (int i = rectangle.X; i < rectangle.X + rectangle.Width; i++)
                            {
                                var ju = rectangle.Y;
                                var jd = rectangle.Y + rectangle.Height;

                                var _pu = p + ju * dataNew.Stride + i * 3;
                                var _pd = p + jd * dataNew.Stride + i * 3;
                                _pu[2] = _pd[2] = 255;
                                _pu[1] = _pd[1] = 0;
                                _pu[0] = _pd[0] = 0;
                            }

                            for (int j = rectangle.Y; j < rectangle.Y + rectangle.Height; j++)
                            {
                                var il = rectangle.X;
                                var ir = rectangle.X + rectangle.Width;

                                var _pl = p + j * dataNew.Stride + il * 3;
                                var _pr = p + j * dataNew.Stride + ir * 3;
                                _pl[2] = _pr[2] = 255;
                                _pl[1] = _pr[1] = 0;
                                _pl[0] = _pr[0] = 0;
                            }
                        }
                    }
                }

                obm.UnlockBits(dataNew);

                /*
                 * 计时器结束
                 */
                pt.Stop();

                setResult(obm, "画矩形 用时：" + pt.Duration);

                MessageBox.Show(str, "药品名称");
            }
            else
            {
                MessageBox.Show("不是上海发票影像", "信息提示");
            }
        }

        //上海发票药品多行处理
        private void shangHaiMoreColumnToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            /*
             * 计时器开始
             */
            var pt = new HiPerfTimer();
            pt.Start();

            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(ref bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw); //找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih); //找竖线
            var hLinesCount = hLines.Count;
            var vLinesCount = vLines.Count;
            var tinnerHLines = new List<Line>();
            var tinnerVLines = new List<Line>();

            if (hLinesCount > 0)
            {
                //将所有横线细化
                tinnerHLines = ImageAnalysis.GetTinnerLines(hLines);
                //去噪音线
                tinnerHLines = ImageAnalysis.DeleteNoiseLines(tinnerHLines, tinnerVLines, 28, iw / 4);
            }

            if (vLinesCount > 0)
            {
                //将所有竖线细化
                tinnerVLines = ImageAnalysis.GetTinnerLines(vLines);
                //去噪音线
                tinnerVLines = ImageAnalysis.DeleteNoiseLines(tinnerVLines, tinnerHLines, 50, ih / 4);
            }

            if (hLinesCount > 0 && vLinesCount > 0)
            {

                //去边界线
                ImageAnalysis.DeleteEdgeLines(ref tinnerHLines, ref tinnerVLines, iw, ih);
                //直线修正
                ImageAnalysis.CorrectLines(ref tinnerHLines, ref tinnerVLines, 50);
            }

            var contentRectangle = new Rectangle(0, 0, iw, ih);
            var imageType = ImageAnalysis.AnalysicImageClass(tinnerHLines, tinnerVLines, iw, ih, ref contentRectangle);
            var obm = new Bitmap(contentRectangle.Width, contentRectangle.Height);
            var data = bm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            var dataObm = obm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height),
                                       ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            //提取药品内容区
            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();
                var ptr2 = (byte*)dataObm.Scan0.ToPointer();

                for (int i = contentRectangle.X; i < contentRectangle.Width + contentRectangle.X; i++)
                {
                    for (int j = contentRectangle.Y; j < contentRectangle.Height + contentRectangle.Y; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        var _ptr2 = ptr2 + (j - contentRectangle.Y) * dataObm.Stride + (i - contentRectangle.X) * 3;
                        _ptr2[2] = _ptr[2];
                        _ptr2[1] = _ptr[1];
                        _ptr2[0] = _ptr[0];
                    }
                }
            }

            bm.UnlockBits(data);
            obm.UnlockBits(dataObm);

            if (imageType == ImageType.Bill)
            {
                var gs = Common.ToBinary(obm, Matlab.GetThreshold(obm));
                var pgs = Projection.HorizontalProjection(gs);
                var listRectangleRow = ImageAnalysis.GetRowArea(pgs, contentRectangle.Width, contentRectangle.Height, 50, 20);
                var listRectangles = ImageAnalysis.AnalysisColumn3(gs, listRectangleRow);

                var str = "";
                foreach (var rectangles in listRectangles)
                {
                    var _path = ConfigOpration.SavePath + listRectangles.IndexOf(rectangles) + "\\";
                    if (!Directory.Exists(_path))
                    {
                        Directory.CreateDirectory(_path);
                    }
                    //将每个矩形区域保存为 tif 格式的图片
                    ImageAnalysis.SaveImageToTif(new Bitmap(obm), rectangles, _path);

                    for (int i = 1; i <= rectangles.Count; i++)
                    {
                        var _pathImg = _path + i + ".tif";
                        var s = "";
                        if (OCR.ImageToOCR(_pathImg, ref s))
                        {
                            str += s + "\r\n";
                        }
                    }
                }

                var dataNew = obm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height),
                                           ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

                unsafe
                {
                    var p = (byte*)dataNew.Scan0.ToPointer();

                    foreach (var rectangles in listRectangles)
                    {
                        foreach (var rectangle in rectangles)
                        {
                            for (int i = rectangle.X; i < rectangle.X + rectangle.Width; i++)
                            {
                                var ju = rectangle.Y;
                                var jd = rectangle.Y + rectangle.Height;

                                var _pu = p + ju * dataNew.Stride + i * 3;
                                var _pd = p + jd * dataNew.Stride + i * 3;
                                _pu[2] = _pd[2] = 255;
                                _pu[1] = _pd[1] = 0;
                                _pu[0] = _pd[0] = 0;
                            }

                            for (int j = rectangle.Y; j < rectangle.Y + rectangle.Height; j++)
                            {
                                var il = rectangle.X;
                                var ir = rectangle.X + rectangle.Width;

                                var _pl = p + j * dataNew.Stride + il * 3;
                                var _pr = p + j * dataNew.Stride + ir * 3;
                                _pl[2] = _pr[2] = 255;
                                _pl[1] = _pr[1] = 0;
                                _pl[0] = _pr[0] = 0;
                            }
                        }
                    }
                }

                obm.UnlockBits(dataNew);

                /*
                 * 计时器结束
                 */
                pt.Stop();

                //清空文件夹
                //FileClean.Clean(ConfigOpration.SavePath);

                setResult(obm, "画矩形 用时：" + pt.Duration);

                MessageBox.Show(str, "药品名称");
            }
            else
            {
                MessageBox.Show("不是上海发票影像", "信息提示");
            }
        }

        //上海发票原图处理
        private void shanghaiOriginalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            /*
             * 计时器开始
             */
            var pt = new HiPerfTimer();
            pt.Start();

            var originalBm = new Bitmap(curBitmap);
            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(ref bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw); //找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih); //找竖线
            var hLinesCount = hLines.Count;
            var vLinesCount = vLines.Count;
            var tinnerHLines = new List<Line>();
            var tinnerVLines = new List<Line>();

            if (hLinesCount > 0)
            {
                //将所有横线细化
                tinnerHLines = ImageAnalysis.GetTinnerLines(hLines);
                //去噪音线
                tinnerHLines = ImageAnalysis.DeleteNoiseLines(tinnerHLines, tinnerVLines, 28, iw / 4);
            }

            if (vLinesCount > 0)
            {
                //将所有竖线细化
                tinnerVLines = ImageAnalysis.GetTinnerLines(vLines);
                //去噪音线
                tinnerVLines = ImageAnalysis.DeleteNoiseLines(tinnerVLines, tinnerHLines, 50, ih / 4);
            }

            if (hLinesCount > 0 && vLinesCount > 0)
            {

                //去边界线
                ImageAnalysis.DeleteEdgeLines(ref tinnerHLines, ref tinnerVLines, iw, ih);
                //直线修正
                ImageAnalysis.CorrectLines(ref tinnerHLines, ref tinnerVLines, 50);
            }

            var contentRectangle = new Rectangle(0, 0, iw, ih);
            var imageType = ImageAnalysis.AnalysicImageClass(tinnerHLines, tinnerVLines, iw, ih, ref contentRectangle);
            var obm = new Bitmap(contentRectangle.Width, contentRectangle.Height);
            var data = bm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            var dataObm = obm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height),
                                       ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            //提取药品内容区
            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();
                var ptr2 = (byte*)dataObm.Scan0.ToPointer();

                for (int i = contentRectangle.X; i < contentRectangle.Width + contentRectangle.X; i++)
                {
                    for (int j = contentRectangle.Y; j < contentRectangle.Height + contentRectangle.Y; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        var _ptr2 = ptr2 + (j - contentRectangle.Y) * dataObm.Stride + (i - contentRectangle.X) * 3;
                        _ptr2[2] = _ptr[2];
                        _ptr2[1] = _ptr[1];
                        _ptr2[0] = _ptr[0];
                    }
                }
            }

            bm.UnlockBits(data);
            obm.UnlockBits(dataObm);

            var oData = originalBm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadWrite,
                                            PixelFormat.Format24bppRgb);
            var areaBm = new Bitmap(contentRectangle.Width, contentRectangle.Height);
            var areaBmData = areaBm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height),
                                       ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            //原图提取药品内容区
            unsafe
            {
                var ptr = (byte*)oData.Scan0.ToPointer();
                var ptr2 = (byte*)areaBmData.Scan0.ToPointer();

                for (int i = contentRectangle.X; i < contentRectangle.Width + contentRectangle.X; i++)
                {
                    for (int j = contentRectangle.Y; j < contentRectangle.Height + contentRectangle.Y; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        var _ptr2 = ptr2 + (j - contentRectangle.Y) * dataObm.Stride + (i - contentRectangle.X) * 3;
                        _ptr2[2] = _ptr[2];
                        _ptr2[1] = _ptr[1];
                        _ptr2[0] = _ptr[0];
                    }
                }
            }

            originalBm.UnlockBits(oData);
            areaBm.UnlockBits(areaBmData);

            if (imageType == ImageType.Bill)
            {
                var gs = Common.ToBinary(obm, Matlab.GetThreshold(obm));
                var pgs = Projection.HorizontalProjection(gs);
                var listRectangleRow = ImageAnalysis.GetRowArea(pgs, contentRectangle.Width, contentRectangle.Height, 50, 20);
                var listRectangles = ImageAnalysis.AnalysisColumn3(gs, listRectangleRow);

                var str = "";
                foreach (var rectangles in listRectangles)
                {
                    var _path = ConfigOpration.SavePath + listRectangles.IndexOf(rectangles) + "\\";
                    if (!Directory.Exists(_path))
                    {
                        Directory.CreateDirectory(_path);
                    }
                    //将每个矩形区域保存为 tif 格式的图片
                    ImageAnalysis.SaveImageToTif(new Bitmap(areaBm), rectangles, _path);

                    for (int i = 1; i <= rectangles.Count; i++)
                    {
                        var _pathImg = _path + i + ".tif";
                        var s = "";
                        if (OCR.ImageToOCR(_pathImg, ref s))
                        {
                            str += s + "\r\n";
                        }
                    }
                }

                var dataNew = areaBm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height),
                                           ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

                unsafe
                {
                    var p = (byte*)dataNew.Scan0.ToPointer();

                    foreach (var rectangles in listRectangles)
                    {
                        foreach (var rectangle in rectangles)
                        {
                            for (int i = rectangle.X; i < rectangle.X + rectangle.Width; i++)
                            {
                                var ju = rectangle.Y;
                                var jd = rectangle.Y + rectangle.Height;

                                var _pu = p + ju * dataNew.Stride + i * 3;
                                var _pd = p + jd * dataNew.Stride + i * 3;
                                _pu[2] = _pd[2] = 255;
                                _pu[1] = _pd[1] = 0;
                                _pu[0] = _pd[0] = 0;
                            }

                            for (int j = rectangle.Y; j < rectangle.Y + rectangle.Height; j++)
                            {
                                var il = rectangle.X;
                                var ir = rectangle.X + rectangle.Width;

                                var _pl = p + j * dataNew.Stride + il * 3;
                                var _pr = p + j * dataNew.Stride + ir * 3;
                                _pl[2] = _pr[2] = 255;
                                _pl[1] = _pr[1] = 0;
                                _pl[0] = _pr[0] = 0;
                            }
                        }
                    }
                }

                areaBm.UnlockBits(dataNew);

                /*
                 * 计时器结束
                 */
                pt.Stop();

                //清空文件夹
                //FileClean.Clean(ConfigOpration.SavePath);

                setResult(areaBm, "画矩形 用时：" + pt.Duration);

                MessageBox.Show(str, "药品名称");
            }
            else
            {
                MessageBox.Show("不是上海发票影像", "信息提示");
            }
        }

        #endregion

        #region 列表影像识别

        //仅横线明细单横线之间投影
        private void rangeHLineProjectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            /*
             * 计时器开始
             */
            var pt = new HiPerfTimer();
            pt.Start();

            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw);//找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih);//找竖线
            var hLinesCount = hLines.Count;
            var vLinesCount = vLines.Count;
            var tinnerHLines = new List<Line>();
            var tinnerVLines = new List<Line>();

            if (hLinesCount > 0)
            {
                //将所有横线细化
                tinnerHLines = ImageAnalysis.GetTinnerLines(hLines);
                //去噪音线
                tinnerHLines = ImageAnalysis.DeleteNoiseLines(tinnerHLines, tinnerVLines, 28, iw / 4);
            }

            if (vLinesCount > 0)
            {
                //将所有竖线细化
                tinnerVLines = ImageAnalysis.GetTinnerLines(vLines);
                //去噪音线
                tinnerVLines = ImageAnalysis.DeleteNoiseLines(tinnerVLines, tinnerHLines, 50, ih / 4);
            }

            if (hLinesCount > 0 && vLinesCount > 0)
            {
                //去边界线
                ImageAnalysis.DeleteEdgeLines(ref tinnerHLines, ref tinnerVLines, iw, ih);
                //直线修正
                ImageAnalysis.CorrectLines(ref tinnerHLines, ref tinnerVLines, 50);
            }

            if (tinnerHLines.Count > 0)
            {
                var gs = new byte[iw, ih];
                for (int i = 1; i <= tinnerHLines.Count; i++)
                {
                    if (i != tinnerHLines.Count)
                    {
                        Projection.VerticalUpProjection(im, ref gs, iw, tinnerHLines[i].A - tinnerHLines[i - 1].A - 20,
                                                     tinnerHLines[i - 1].A + 10);
                    }
                    else
                    {
                        Projection.VerticalUpProjection(im, ref gs, iw, ih - tinnerHLines[i - 1].A - 20,
                                                     tinnerHLines[i - 1].A + 10);
                    }
                }

                var obm = Common.ToBitmap(im);
                var data = obm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
                unsafe
                {
                    var ptr = (byte*)data.Scan0.ToPointer();
                    for (int j = 0; j < ih; j++)
                    {
                        for (int i = 0; i < iw; i++)
                        {
                            var p = ptr + j * data.Stride + i * 3;
                            if (gs[i, j] == 0)
                            {
                                p[0] = p[1] = p[2] = 255;
                            }
                            else
                            {
                                p[0] = p[1] = p[2] = 0;
                            }
                        }
                    }
                }
                obm.UnlockBits(data);
                setResult(obm, "横线之间向上投影");
            }
        }

        //仅横线明细单药品识别
        private void onlyHLineOCRToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        //表格明细单药品识别
        private void tableAreaOCRToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        //带框明细单药品识别
        private void frameAreaOCRToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();

            /*
             * 计时器开始
             */
            var pt = new HiPerfTimer();
            pt.Start();

            var bm = new Bitmap(curBitmap);
            var im = Common.ToBinary(bm, Matlab.GetThreshold(bm));
            var hLines = ImageAnalysis.FindHorizontalLines(im, 8, iw / 5, iw);//找横线
            var vLines = ImageAnalysis.FindVerticalLines(im, 8, ih / 8, ih);//找竖线
            var hLinesCount = hLines.Count;
            var vLinesCount = vLines.Count;
            var tinnerHLines = new List<Line>();
            var tinnerVLines = new List<Line>();

            if (hLinesCount > 0)
            {
                //将所有横线细化
                tinnerHLines = ImageAnalysis.GetTinnerLines(hLines);
                //去噪音线
                tinnerHLines = ImageAnalysis.DeleteNoiseLines(tinnerHLines, tinnerVLines, 28, iw / 4);
            }

            if (vLinesCount > 0)
            {
                //将所有竖线细化
                tinnerVLines = ImageAnalysis.GetTinnerLines(vLines);
                //去噪音线
                tinnerVLines = ImageAnalysis.DeleteNoiseLines(tinnerVLines, tinnerHLines, 50, ih / 4);
            }

            if (hLinesCount > 0 && vLinesCount > 0)
            {
                //去边界线
                ImageAnalysis.DeleteEdgeLines(ref tinnerHLines, ref tinnerVLines, iw, ih);
                //直线修正
                ImageAnalysis.CorrectLines(ref tinnerHLines, ref tinnerVLines, 50);
            }

            var contentRectangle = new Rectangle(0, 0, 0, 0);
            var imageType = ImageAnalysis.AnalysicImageClass(tinnerHLines, tinnerVLines, iw, ih, ref contentRectangle);

            if (imageType == ImageType.FrameDetail)
            {
                //找直线交点
                var nodeList = ImageAnalysis.GetLinesNodes(tinnerHLines, tinnerVLines);
                contentRectangle = ImageAnalysis.FindFrameImageContentArea(nodeList);
                contentRectangle.X = contentRectangle.X + 5;
                contentRectangle.Y = contentRectangle.Y + 5;
                contentRectangle.Width = contentRectangle.Width - 5;
                contentRectangle.Height = contentRectangle.Height - 5;
            }
            var data = bm.LockBits(new Rectangle(0, 0, iw, ih), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            var obm = new Bitmap(contentRectangle.Width, contentRectangle.Height);
            var dataObm = obm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height), ImageLockMode.WriteOnly,
                                       PixelFormat.Format24bppRgb);

            unsafe
            {
                var ptr = (byte*)data.Scan0.ToPointer();
                var ptr2 = (byte*)dataObm.Scan0.ToPointer();

                for (int i = contentRectangle.X; i < contentRectangle.Width + contentRectangle.X; i++)
                {
                    for (int j = contentRectangle.Y; j < contentRectangle.Height + contentRectangle.Y; j++)
                    {
                        var _ptr = ptr + j * data.Stride + i * 3;
                        var _ptr2 = ptr2 + (j - contentRectangle.Y) * dataObm.Stride + (i - contentRectangle.X) * 3;
                        _ptr2[2] = _ptr[2];
                        _ptr2[1] = _ptr[1];
                        _ptr2[0] = _ptr[0];
                    }
                }
            }

            bm.UnlockBits(data);
            obm.UnlockBits(dataObm);

            if (imageType == ImageType.FrameDetail)
            {
                var gs = Common.ToBinary(obm, Matlab.GetThreshold(obm));
                gs = Matlab.Dilate(obm, gs, 1);
                gs = Matlab.Erode(gs, contentRectangle.Width, contentRectangle.Height, 1);
                var pgs = Projection.HorizontalProjection(gs);
                obm = Common.ToBitmap(gs);
                var listRectangleRow = ImageAnalysis.GetRowArea(pgs, contentRectangle.Width, contentRectangle.Height, 50, 20);
                var listRectangles = ImageAnalysis.AnalysisColumn2(gs, listRectangleRow);

                var str = "";
                foreach (var rectangles in listRectangles)
                {
                    var _path = ConfigOpration.SavePath + listRectangles.IndexOf(rectangles) + "\\";
                    if (!Directory.Exists(_path))
                    {
                        Directory.CreateDirectory(_path);
                    }
                    //将每个矩形区域保存为 tif 格式的图片
                    ImageAnalysis.SaveImageToTif(new Bitmap(obm), rectangles, _path);

                    for (int i = 1; i <= rectangles.Count; i++)
                    {
                        var _pathImg = _path + i + ".tif";
                        var s = "";
                        if (OCR.ImageToOCR(_pathImg, ref s))
                        {
                            str += s + "\r\n";
                        }
                    }
                }

                var dataNew = obm.LockBits(new Rectangle(0, 0, contentRectangle.Width, contentRectangle.Height),
                                           ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

                unsafe
                {
                    var p = (byte*)dataNew.Scan0.ToPointer();

                    foreach (var rectangles in listRectangles)
                    {
                        foreach (var rectangle in rectangles)
                        {
                            for (int i = rectangle.X; i < rectangle.X + rectangle.Width; i++)
                            {
                                var ju = rectangle.Y;
                                var jd = rectangle.Y + rectangle.Height;

                                var _pu = p + ju * dataNew.Stride + i * 3;
                                var _pd = p + jd * dataNew.Stride + i * 3;
                                _pu[2] = _pd[2] = 255;
                                _pu[1] = _pd[1] = 0;
                                _pu[0] = _pd[0] = 0;
                            }

                            for (int j = rectangle.Y; j < rectangle.Y + rectangle.Height; j++)
                            {
                                var il = rectangle.X;
                                var ir = rectangle.X + rectangle.Width;

                                var _pl = p + j * dataNew.Stride + il * 3;
                                var _pr = p + j * dataNew.Stride + ir * 3;
                                _pl[2] = _pr[2] = 255;
                                _pl[1] = _pr[1] = 0;
                                _pl[0] = _pr[0] = 0;
                            }
                        }
                    }
                }

                obm.UnlockBits(dataNew);

                /*
                 * 计时器结束
                 */
                pt.Stop();

                setResult(obm, "画矩形 用时：" + pt.Duration);

                MessageBox.Show(str, "药品名称");
            }
            else
            {
                setResult(bm, "非带框影像");
            }
        }

        #endregion

        //影像处理及扫描
        private void provincialCharacteristicsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getCurrentImage();
            var bm = new Bitmap(curBitmap);

            var pt = new HiPerfTimer();
            pt.Start();

            var ms = ImageOCR.ImageMedicineOCR.GetMedicineList(bm);

            pt.Stop();

            var s = "";
            if (ms.Count > 0)
            {
                foreach (var medicine in ms)
                {
                    s += medicine.MedicineName + "【" + medicine.Area + "】\r\n";
                }
            }
            MessageBox.Show(s, "Message [Elapsed time" + pt.Duration + "]");
        }

        //数据库匹配
        private void dbMatchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var open = new OpenFileDialog();
            if (open.ShowDialog() == DialogResult.OK)
            {
                var path = open.FileName;
                var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
                var sr = new StreamReader(fs, Encoding.Default);
                string str = sr.ReadLine();
                while (str != null)
                {
                    if (str != "")
                    {
                        var allMedicines = new MatchMedicine();
                        string matchtMedicine = string.Empty;
                        if (MatchMedicine.IsRefeshData)
                        {
                            MatchMedicine.AllMedicines = allMedicines.SelectMedicine();
                            MatchMedicine.IsRefeshData = false;
                        }

                        //获取与字符串符合的药品
                        var hasMatch = allMedicines.SimilarMatching(str, ref matchtMedicine, 55);

                        if (hasMatch)
                        {
                            LogService.Info("\r\n" + str + "\r\nMacth:" + matchtMedicine);
                        }
                    }

                    str = sr.ReadLine();
                }
                sr.Close();
                fs.Close();
                MessageBox.Show("执行完毕", "Message");
            }
        }

        #endregion

        #region 常用功能

        //解压压缩文件
        private void unZipToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            var open = new FolderBrowserDialog { Description = "请选择要批量处理的文件夹路径" };
            if (open.ShowDialog() == DialogResult.OK)
            {
                var path = open.SelectedPath;
                DialogResult msgBoxResult = MessageBox.Show(
                    "是否解压到同一目录？",//对话框的显示内容
                    "信息提示",//对话框的标题
                    MessageBoxButtons.YesNo,//定义对话框的按钮，这里定义了YSE和NO两个按钮     
                    MessageBoxIcon.Information, //定义对话框内的图表式样
                    MessageBoxDefaultButton.Button2//定义对话框的按钮式样
                    );

                string newPath = msgBoxResult == DialogResult.Yes ? UnZip.Unzip(path) : UnZip.Unzip(path, false);

                DialogResult msgBoxResult2 = MessageBox.Show(
                        "解压成功，请查看Debug\\Temp目录下同名文件夹。\r\n是否打开该目录？",//对话框的显示内容
                        "信息提示",//对话框的标题
                        MessageBoxButtons.YesNo,//定义对话框的按钮，这里定义了YSE和NO两个按钮     
                        MessageBoxIcon.Information, //定义对话框内的图表式样
                        MessageBoxDefaultButton.Button1//定义对话框的按钮式样
                        );
                if (msgBoxResult2 == DialogResult.Yes)
                {
                    System.Diagnostics.Process.Start("explorer.exe", AppDomain.CurrentDomain.BaseDirectory + "temp\\" + newPath);
                }
            }
        }

        //解析XML
        private void parserXMLToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            var open = new FolderBrowserDialog { Description = "请选择文件夹" };
            if (open.ShowDialog() == DialogResult.OK)
            {
                var path = open.SelectedPath;
                var newFileName = path.Substring(path.LastIndexOf('\\') + 1);
                var xmlDetails = XmlParser.ReadXmlFile(path);
                var str = "";
                var total = 0;
                foreach (var xmlDetailse in xmlDetails)
                {
                    var strMedicine = "";
                    foreach (List<string> ms in xmlDetailse.DicMedicine.Values)
                    {
                        total += ms.Count;
                        foreach (var m in ms)
                        {
                            strMedicine += m + " | ";
                        }
                    }
                    str += xmlDetailse.FileName + "\r\n" + "图片数：" + xmlDetailse.ImageCount + " 药品数：" +
                              xmlDetailse.MedicineCount + " 药品名：" + strMedicine + "\r\n";
                }
                if (!Directory.Exists("Temp"))
                {
                    Directory.CreateDirectory("Temp");
                }

                File.WriteAllText("Temp\\" + newFileName + ".txt", str + "\r\n\r\n" + "药品总数：" + total);
                DialogResult msgBoxResult = MessageBox.Show(
                        "XML文件解析成功，请查看Debug\\Temp目录下同名文件。\r\n是否打开该目录？",//对话框的显示内容
                        "信息提示",//对话框的标题
                        MessageBoxButtons.YesNo,//定义对话框的按钮，这里定义了YSE和NO两个按钮     
                        MessageBoxIcon.Information, //定义对话框内的图表式样
                        MessageBoxDefaultButton.Button1//定义对话框的按钮式样
                        );
                if (msgBoxResult == DialogResult.Yes)
                {
                    System.Diagnostics.Process.Start("explorer.exe", AppDomain.CurrentDomain.BaseDirectory + "Temp\\" + newFileName + ".txt");
                }
            }
        }

        //图像批量处理-批量黑白反色
        private void batchBrackToWhiteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var open = new FolderBrowserDialog { Description = "请选择要批量处理的文件夹路径" };
            if (open.ShowDialog() == DialogResult.OK)
            {
                var path = open.SelectedPath;
                var newPath = Features.BatchBrackToWihte(path);
                DialogResult msgBoxResult = MessageBox.Show(
                        "批量处理成功，请查看Debug\\Temp目录下同名文件夹。\r\n是否打开该目录？",//对话框的显示内容
                        "信息提示",//对话框的标题
                        MessageBoxButtons.YesNo,//定义对话框的按钮，这里定义了YSE和NO两个按钮     
                        MessageBoxIcon.Information, //定义对话框内的图表式样
                        MessageBoxDefaultButton.Button1//定义对话框的按钮式样
                        );
                if (msgBoxResult == DialogResult.Yes)
                {
                    System.Diagnostics.Process.Start("explorer.exe", AppDomain.CurrentDomain.BaseDirectory + newPath);
                }
            }
        }

        //图像批量处理-批量格式转换
        private void batchFormatToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var open = new FolderBrowserDialog { Description = "请选择要批量处理的文件夹路径" };
            if (open.ShowDialog() == DialogResult.OK)
            {
                var dialog = new ImageFormatDialog();

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    var str = dialog.GetFormat();
                    ImageFormat format = ImageFormat.Tiff;
                    switch (str)
                    {
                        case "Jpeg":
                            format = ImageFormat.Jpeg;
                            break;
                        case "Bmp":
                            format = ImageFormat.Bmp;
                            break;
                        case "Gif":
                            format = ImageFormat.Gif;
                            break;
                        case "Png":
                            format = ImageFormat.Png;
                            break;
                        case "Wmf":
                            format = ImageFormat.Wmf;
                            break;
                    }
                    var path = open.SelectedPath;
                    var newPath = Features.BatchImageFormat(path, format);
                    DialogResult msgBoxResult = MessageBox.Show(
                        "批量格式化成功，请查看Debug\\Temp目录下同名文件夹。\r\n是否打开该目录？",//对话框的显示内容
                        "信息提示",//对话框的标题
                        MessageBoxButtons.YesNo,//定义对话框的按钮，这里定义了YSE和NO两个按钮     
                        MessageBoxIcon.Information, //定义对话框内的图表式样
                        MessageBoxDefaultButton.Button1//定义对话框的按钮式样
                        );
                    if (msgBoxResult == DialogResult.Yes)
                    {
                        System.Diagnostics.Process.Start("explorer.exe", AppDomain.CurrentDomain.BaseDirectory + newPath);
                    }
                }
            }
        }

        //图像批量处理-批量边缘扩张
        private void batchEageEnlargerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var open = new FolderBrowserDialog { Description = "请选择要批量处理的文件夹路径" };
            if (open.ShowDialog() == DialogResult.OK)
            {
                var dialog = new WidthAndHeightEnlargeSetting();

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    var path = open.SelectedPath;
                    var enWidth = Convert.ToInt32(dialog.GetEnWidth.Trim());
                    var enHeight = Convert.ToInt32(dialog.GetEnHeight.Trim());
                    var newPath = Features.BatchEageEnlarger(path, enWidth, enHeight);
                    DialogResult msgBoxResult = MessageBox.Show(
                        "批量边缘扩张成功，请查看Debug\\Temp目录下同名文件夹。\r\n是否打开该目录？",//对话框的显示内容
                        "信息提示",//对话框的标题
                        MessageBoxButtons.YesNo,//定义对话框的按钮，这里定义了YSE和NO两个按钮     
                        MessageBoxIcon.Information, //定义对话框内的图表式样
                        MessageBoxDefaultButton.Button1//定义对话框的按钮式样
                        );
                    if (msgBoxResult == DialogResult.Yes)
                    {
                        System.Diagnostics.Process.Start("explorer.exe", AppDomain.CurrentDomain.BaseDirectory + newPath);
                    }
                }
            }
        }

        //批量二值化
        private void bacthTwoValueToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var open = new FolderBrowserDialog { Description = "请选择要批量处理的文件夹路径" };
            if (open.ShowDialog() == DialogResult.OK)
            {
                var newPath = Features.BatchToTwoValue(open.SelectedPath);
                DialogResult msgBoxResult = MessageBox.Show(
                    "批量二值化成功，请查看Debug\\Temp目录下同名文件夹。\r\n是否打开该目录？",//对话框的显示内容
                    "信息提示",//对话框的标题
                    MessageBoxButtons.YesNo,//定义对话框的按钮，这里定义了YSE和NO两个按钮     
                    MessageBoxIcon.Information, //定义对话框内的图表式样
                    MessageBoxDefaultButton.Button1//定义对话框的按钮式样
                    );
                if (msgBoxResult == DialogResult.Yes)
                {
                    System.Diagnostics.Process.Start("explorer.exe", AppDomain.CurrentDomain.BaseDirectory + newPath);
                }
            }
        }

        //批量OCR
        private void batchOCRToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var open = new FolderBrowserDialog { Description = "请选择要批量处理的文件夹路径" };
            if (open.ShowDialog() == DialogResult.OK)
            {
                var newPath = Features.BatchOCR(open.SelectedPath);
                DialogResult msgBoxResult = MessageBox.Show(
                    "批量OCR处理完成，请查看Debug\\Temp目录下同名文件夹。\r\n是否打开该目录？",//对话框的显示内容
                    "信息提示",//对话框的标题
                    MessageBoxButtons.YesNo,//定义对话框的按钮，这里定义了YSE和NO两个按钮     
                    MessageBoxIcon.Information, //定义对话框内的图表式样
                    MessageBoxDefaultButton.Button1//定义对话框的按钮式样
                    );
                if (msgBoxResult == DialogResult.Yes)
                {
                    System.Diagnostics.Process.Start("explorer.exe", AppDomain.CurrentDomain.BaseDirectory + newPath);
                }
            }
        }

        //批量去噪
        private void batchDenoisingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var open = new FolderBrowserDialog { Description = "请选择要批量处理的文件夹路径" };
            if (open.ShowDialog() == DialogResult.OK)
            {
                var newPath = Features.BatchDenoising(open.SelectedPath);
                DialogResult msgBoxResult = MessageBox.Show(
                    "批量去噪处理完成，请查看Debug\\Temp目录下同名文件夹。\r\n是否打开该目录？",//对话框的显示内容
                    "信息提示",//对话框的标题
                    MessageBoxButtons.YesNo,//定义对话框的按钮，这里定义了YSE和NO两个按钮     
                    MessageBoxIcon.Information, //定义对话框内的图表式样
                    MessageBoxDefaultButton.Button1//定义对话框的按钮式样
                    );
                if (msgBoxResult == DialogResult.Yes)
                {
                    System.Diagnostics.Process.Start("explorer.exe", AppDomain.CurrentDomain.BaseDirectory + newPath);
                }
            }
        }

        #endregion

        #region Test Button

        //测试
        private void testToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var str = "枯在颗在大都是枯叶在夺枯叶枯kjfksdf";
            MessageBox.Show(SHA512(str), "Message");
        }

        #endregion

        private string SHA512(string strPlain)
        {
            var sha512 = new SHA512Managed();
            string strHash = string.Empty;
            byte[] btHash = sha512.ComputeHash(Encoding.Unicode.GetBytes(strPlain));
            for (int i = 0; i < btHash.Length; i++)
            {
                strHash = strHash + Convert.ToString(btHash[i], 16);
            }
            return strHash;
        }

        #endregion

        #region Method

        //get pictureBox1's image
        private void getCurrentImage()
        {
            if (pictureBox1.Image == null)
            {
                MessageBox.Show("请选择一张图片。", "提示信息");

                var open = new OpenFileDialog
                {
                    Filter = "Image file(*.bmp;*.jpg;*gif;*png;*tif;*wmf)|*.bmp;*.jpg;*gif;*png;*tif;*wmf"
                };

                if (open.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        curBitmap = (Bitmap)Image.FromFile(open.FileName);
                        //imagePath = 
                    }
                    catch (Exception exp)
                    {
                        MessageBox.Show(exp.Message);
                    }

                    pictureBox1.Refresh();
                    pictureBox1.Image = curBitmap;
                    label1.Text = "原图";
                }
                else
                {
                    getCurrentImage();
                }
            }
        }

        //set pictureBox2's image and label2's text
        private void setResult(Bitmap bitmap, string text)
        {
            pictureBox2.Refresh();
            pictureBox2.Image = bitmap;
            label2.Text = text;
        }

        /// <summary>
        /// 记录药品名称与对应位置（x、y坐标）
        /// </summary>
        /// <param name="ms">包含药品位置与名称的集合</param>
        /// <returns>分列后的药品集合字典</returns>
        public static Dictionary<int, List<Medicine>> AnalysisMedichine(List<Medicine> ms)
        {
            var column = new Dictionary<int, List<Medicine>>();
            foreach (var m in ms)
            {

                if (!column.ContainsKey(m.X))
                {
                    column.Add(m.X, new List<Medicine> { m });
                }
                else
                {
                    column[m.X].Add(m);
                }
            }

            return column;
        }

        #endregion

    }
}
